Das Veranstaltungssystem basiert auf Jekyll mit Decap CMS und besteht aus folgenden Komponenten:
_events/ # Collection für alle Veranstaltungen
_data/
event_types.yml # Zentrale Definition der Event-Typen (Single Source of Truth)
_layouts/
event.html # Layout für Event-Detailseiten
_includes/
event-card.html # Wiederverwendbare Event-Karte
pagination.html # Pagination-Komponente
event-filters.html # Filter-Buttons
head/
custom.html # CSS-Einbindung
_pages/
veranstaltungen.md # Hauptübersicht (4 zukünftig + 2 vergangen)
veranstaltungen-archiv.md # Alle vergangenen Events
veranstaltungen-zukunft.md # Alle zukünftigen Events
admin/
config.yml # Decap CMS Konfiguration
index.html # Admin-Interface mit Type-Defaults
assets/
css/
events.css # Event-System Styling (BEM-Architektur)
js/
event-filters.js # Client-seitige Filter-Logik
feeds/
mintfv-events.ical # iCal Feed (RFC 5545)
mintfv-events.xml # RSS 2.0 Feed
Entscheidung: EINE Collection _events mit event_type Attribut statt separate Collections.
Vorteile:
Implementierung:
# _config.yml
collections:
events:
output: true
permalink: /veranstaltungen/:categories/:title/
Entscheidung: _data/event_types.yml als Single Source of Truth für:
Vorteile:
Verwendung:
Herausforderung: Decap CMS unterstützt keine nativen type-abhängigen Defaults.
Lösung: JavaScript Event-Listener in admin/index.html
event_type Select-ElementLimitation: Funktioniert nur beim Erstellen neuer Events, nicht beim Bearbeiten.
Entscheidung: Automatisches CREATED-Feld für RFC 5545 Compliance.
Regel:
Implementierung auf 3 Ebenen:
applyDefaults()Vorteil:
Migration: Script _scripts/add_created_field.rb für bestehende Events.
LAST-MODIFIED: Wird bei jeder Bearbeitung automatisch aktualisiert.
Entscheidung: Liquid-Templates für Zeitfilterung statt Jekyll-Pagination-Plugin.
Vorteile:
Implementierung:
Entscheidung: BEM (Block Element Modifier) Methodik
Struktur:
.event-card { } /* Block */
.event-card__title { } /* Element */
.event-card--past { } /* Modifier */
Vorteile:
# Pflichtfelder
event_type: "mach-mit-mathe" | "offene-werkstatt" | "ferienpass" | "sonstige"
title: String
start_date: DateTime (YYYY-MM-DD HH:mm)
excerpt: String (10-200 Zeichen)
published: Boolean
created: DateTime (YYYY-MM-DD HH:mm) # Automatisch gesetzt
last_modified: DateTime (YYYY-MM-DD HH:mm) # Automatisch aktualisiert
sequence: Integer # Revisions-Zähler (startet bei 0, +1 bei jeder Änderung)
# Optionale Felder
end_date: DateTime
location: String
teaser_image: Path
teaser_alt: String
gallery:
- image: Path
caption: String
registration_required: Boolean
registration_email: String
registration_deadline: Date
max_participants: Integer
age_group: String
cost: String
organizers: Array[String]
notes: Text
cancelled: Boolean
Ziel: Mix aus Zukunft und Vergangenheit für Kontinuität
Algorithmus:
start_date sortierenupcoming und past Arrays aufteilen (basierend auf site.time)upcoming nehmenpast nehmen (reversed)Code: _pages/veranstaltungen.md
Technologie: Vanilla JavaScript (ES6+)
Funktionsweise:
.event-card Elemente sammelndata-event-type Attribut prüfendisplay: none ausblendenCode: assets/js/event-filters.js
Implementierung:
.event-card--past {
opacity: 0.7;
filter: grayscale(30%);
}
Anwendung:
Besonderheiten:
TZID=Europe/Berlin für alle ZeitenSTATUS:CANCELLED für abgesagte EventsUID basierend auf Event-ID + DomainValidierung: https://icalendar.org/validator.html
Besonderheiten:
<content:encoded>backend:
name: git-gateway
branch: main
Authentifizierung:
media_folder: "assets/images/events"
public_folder: "/assets/images/events"
Constraints:
Implementierung:
view_filters:
- label: "Mach mit Mathe 🎨"
field: event_type
pattern: 'mach-mit-mathe'
Vorteil: Schneller Zugriff auf Event-Typen ohne Suche
<img loading="lazy" ... >
<article>, <nav>, <time> Tagsaria-label für Filter-Buttonsaria-live="polite" für Zähleraria-current="page" für Paginationtitle wenn leerImplementiert in _layouts/event.html:
{
"@context": "https://schema.org",
"@type": "Event",
"name": "...",
"startDate": "...",
"location": { ... },
...
}
Vorteil: Rich Snippets in Google Search Results
Pattern: /veranstaltungen/:categories/:title/
Beispiel: /veranstaltungen/workshop/nao-roboter-ferienpass/
SEO-Vorteile:
Checkliste:
YAML:
bundle exec jekyll build
HTML: https://validator.w3.org/
CSS: https://jigsaw.w3.org/css-validator/
iCal: https://icalendar.org/validator.html
Workflow:
main Branchgh-pagesBuild-Command:
bundle exec jekyll build
Setup für GitHub Pages ohne Netlify:
Option 1: Netlify Identity (empfohlen)
Option 2: GitHub OAuth App
Anleitung: https://decapcms.org/docs/github-backend/
Monatlich:
Vierteljährlich:
Jährlich:
Automatisch:
Empfehlung:
mainNice-to-have:
Implementierung: Würde Custom-Plugins oder externe Services erfordern.
Checkliste:
published: true gesetzt?start_date im korrekten Format?_config.yml korrekt?Lösung:
_includes/head/custom.html existiertcustom.html korrekt?Checkliste:
event-filters.js geladen?Lösungen:
backend in config.yml korrekt?Website: https://www.mintarium-fv.de/
Repository: https://github.com/MintFV/MintFV.github.io
Issues: https://github.com/MintFV/MintFV.github.io/issues
Pull Requests: Willkommen!
Kontakt: info@mintarium-fv.de
Siehe LICENSE im Repository.
Letzte Aktualisierung: November 2025
Version: 1.0
Autor: GitHub Copilot (Claude Sonnet 4.5)