# Havelseiten Version: `0.7.0` Havelseiten ist ein Anti-CMS fuer schnelle, einfache und datenschutzbewusste Websites. Keine Datenbank, kein Adminbereich, keine Plugins, keine laufenden Updates, kein teurer Webspace. Inhalte liegen als Markdown-Dateien im Ordner `havelseite/`. Der Generator baut daraus fertige statische HTML-Seiten im Ordner `ausgabe/`. Havelseiten ist besonders gedacht fuer Vereine, Initiativen und kleine Projekte, die eine robuste Website brauchen, aber kein Website-System pflegen wollen. ## Grundidee - Markdown rein, fertige Website raus. - Einstellungen stehen in `havelseite/einstellungen.md`, nicht in JSON/YAML. - Externe Inhalte wie YouTube oder OpenStreetMap werden datenschutzfreundlich erst nach Zustimmung geladen. - Die Navigation entsteht automatisch aus Dateien und Ordnern. - Der Validator prueft vor jedem Build auf typische Fehler. - Spaeter kann Galatea als UI davorliegen: Inhalte hochladen, Havelseiten baut, GitLab/Pages veroeffentlicht. ## Was darf ich bearbeiten? Diese Dateien und Ordner sind fuer normale Bearbeitung gedacht: - `havelseite/` fuer Seiten und Texte - `havelseite/medien/` fuer Bilder und Dateien - `havelseite/medien/galerie/` fuer Galerien - `havelseite/medien/logo/` fuer das Logo - `havelseite/einstellungen.md` fuer Titel, Design, Logo, Galerie, Icons und Schrift Den Ordner `generator/` musst du im normalen Alltag nicht anfassen. ## Schnellstart 1. Aendere Titel, Farben, Logo und Navigation in `havelseite/einstellungen.md`. 2. Schreibe deine Startseite in `havelseite/index.md`. 3. Lege weitere Seiten als Markdown-Dateien in `havelseite/` an. 4. Lege Bilder in `havelseite/medien/`. 5. Baue die Website mit `python3 generator/havelseiten.py`. ## Seite bauen ```sh python3 generator/havelseiten.py ``` Vor dem Bauen wird `havelseite/einstellungen.md` automatisch formatiert und danach geprueft. Aus `- [] Wald` wird zum Beispiel `- [ ] Wald`. Warnungen stoppen den Build nicht. Wenn zum Beispiel zwei Farbpaletten angekreuzt sind, wird gewarnt und die erste angekreuzte Palette verwendet. Die fertigen Seiten liegen danach in `ausgabe/`. ## Vorher pruefen ```sh python3 generator/validate.py ``` Der Validator sagt in normalen Worten, wenn zum Beispiel ein Bild fehlt, ein Galerieordner falsch geschrieben ist oder ein unbekannter Block wie `@galry` benutzt wurde. ## Projektstruktur ```text havelseite/ einstellungen.md index.md verein.md regatten/ kon-tiki.md fusszeile/ fusszeile.md impressum.md datenschutz.md medien/ logo/ galerie/ generator/ havelseiten.py validate.py templates/ themes/ ausgabe/ ``` `havelseite/` ist der Inhaltsordner. `generator/` ist die Technik. `ausgabe/` ist das fertige Ergebnis. ## Eine neue Seite anlegen Lege im Ordner `havelseite` eine neue Datei an, zum Beispiel: ```text havelseite/aktuelles.md ``` Inhalt: ```md @aufmacher # Aktuelles Neuigkeiten aus dem Verein. @text # Willkommen Hier steht normaler Text. ``` Nach dem Bauen entsteht: ```text ausgabe/aktuelles.html ``` Die Navigation wird automatisch erstellt. ## Menue sortieren Die Reihenfolge steuerst du ueber Zahlen am Anfang von Datei- oder Ordnernamen: ```text havelseite/01_start.md havelseite/02_verein.md havelseite/03_regatten/ havelseite/04_kontakt.md ``` Die Zahlen sind nur fuer die Sortierung da. Im Menue und in den fertigen Links werden sie ausgeblendet. Havelseiten erlaubt fuer Seiten nur eine Ordnerebene: ```text havelseite/regatten/kon-tiki.md ``` Nicht erlaubt sind Ordner in Ordnern: ```text havelseite/regatten/2026/kon-tiki.md ``` Der Grund: Die Navigation bleibt dadurch einfach. Eine Datei direkt in `havelseite/` wird ein normaler Menuepunkt. Ein Ordner direkt in `havelseite/` wird ein ausklappbarer Menuepunkt. Medienordner duerfen tiefer sein. Diese Regel gilt nur fuer Markdown-Seiten. ## Einstellungen Globale Einstellungen stehen in: ```text havelseite/einstellungen.md ``` Beispiel: ```md # Einstellungen @einstellung:seite Titel: Havelseiten @einstellung:sprache - [x] Deutsch - [ ] Englisch @einstellung:farbpalette - [ ] Havel - [ ] Wasser - [x] Wald - [ ] Sonnenuntergang - [ ] Dunkel - [ ] Küste - [ ] Segel - [ ] Leuchtturm @einstellung:schrift - [ ] klein - [x] mittel - [ ] groß @einstellung:navigation - [ ] klein - [ ] mittel - [x] groß - [x] bleibt oben - [ ] scrollt mit - [ ] links - [x] mittig - [ ] rechts @einstellung:logo - [x] in der Navigation - [x] in der Fußzeile - [x] links - [ ] rechts Logoordner: logo Alternativtext: Märkischer Seglerverein Beetzsee Text: Havelseiten @einstellung:logo-datei - [x] msvb_logo.png @einstellung:mobilmenue - [x] automatisch - [ ] links - [ ] mittig - [ ] rechts - [ ] Untermenüs ausgeklappt @einstellung:bilder - [x] Bildunterschriften - [x] runde Ecken @einstellung:icons - [x] rund - [ ] schlicht - [ ] text @einstellung:datenschutz - [ ] externe Inhalte laden @einstellung:social instagram: https://instagram.com youtube: https://youtube.com ``` Wenn in einer Auswahl nichts angekreuzt ist, setzt der Formatter meistens automatisch das Kreuz bei der ersten Option. Einzelne Ja/Nein-Optionen, zum Beispiel `Untermenüs ausgeklappt`, bleiben ohne Kreuz bewusst ausgeschaltet. ### Logo Lege das Logo in `havelseite/medien/logo/`. Wenn weder `in der Navigation` noch `in der Fußzeile` angekreuzt ist, wird kein Logo angezeigt. Sobald eine dieser beiden Optionen angekreuzt ist, muss auch `links` oder `rechts` angekreuzt sein. Der Formatter ergänzt automatisch eine Auswahl mit den Logo-Dateien: ```md @einstellung:logo-datei - [x] msvb_logo.png - [ ] zweites-logo.svg ``` Wenn nichts angekreuzt ist, wird automatisch die erste Datei angekreuzt. `Logoordner: logo` bedeutet: Der Generator schaut in `havelseite/medien/logo/`. ### Farbpaletten Die Farbpaletten liegen als JSON-Dateien in `generator/themes/`. Wenn dort eine neue Datei wie `verein.json` liegt, ergänzt der Formatter die Auswahl in `havelseite/einstellungen.md` automatisch; danach kann sie als `Verein` angekreuzt werden. Aktuell gibt es: - `Havel` - `Wasser` - `Wald` - `Sonnenuntergang` - `Dunkel` - `Küste` - `Segel` - `Leuchtturm` ### Galerie Die Galerie bleibt bewusst schlicht. Global einstellbar sind nur die Dinge, die sofort sichtbar sind: `Bildunterschriften` und `runde Ecken`. ### Icons Die Social-Icons sind bewusst ohne externes Iconpaket gebaut. Dadurch gibt es keine Lizenz- oder Ladeprobleme. - `rund`: runde kleine Icon-Badges - `schlicht`: kantigere Icon-Badges - `text`: reine Textlinks Social Links werden zentral aus `@einstellung:social` erzeugt. Schreibe sie deshalb nicht noch einmal in `havelseite/fusszeile/fusszeile.md`, sonst stehen sie doppelt im Footer. ### Datenschutz Wenn `externe Inhalte laden` nicht angekreuzt ist, werden externe Karten und YouTube-Videos nicht automatisch geladen. Stattdessen erscheint ein Hinweis mit einem Button zum Nachladen auf derselben Seite. Die Galerie funktioniert ohne externe Skripte und braucht fuer lokale Bilder keine Datenschutzfreigabe. Wenn eine manuelle Galerie externe Bild-URLs verwendet, erscheint ebenfalls ein Button zum Nachladen. ## Bilder und Galerien Normale Bilder legst du unter `havelseite/medien/` ab. ```md ![Beschreibung des Bildes](medien/mein-bild.jpg) ``` Galeriebilder legst du in einen Ordner unter: ```text havelseite/medien/galerie/ ``` Beispiel: ```text havelseite/medien/galerie/Sommerfest/ ``` Dann kannst du die Galerie so einbinden: ```md @galerie:Sommerfest # Sommerfest ``` Beim Klick auf ein Bild oeffnet sich eine Ansicht, in der man durch die Galerie wischen kann. ## Bausteine Deutsch ist die Hauptschreibweise. Die englische Schreibweise funktioniert zusaetzlich. Jeder Baustein beginnt mit `@name`. Der Inhalt darunter gehoert bis zum naechsten `@baustein` zu diesem Bereich. Die Namen folgen einer einfachen Regel: Einzelbereiche stehen im Singular, Listenbereiche im Plural. Darum heisst es `@hinweis`, `@veranstaltung` und `@person`, aber `@kacheln`, `@veranstaltungen`, `@fragen`, `@dateien`, `@personen` und `@sponsoren`. Listen verwenden `##`-Ueberschriften fuer einzelne Eintraege. | Markdown | Englisch | Wird auf der Website zu | | --- | --- | --- | | `@aufmacher` | `@hero` | grosse Medienflaeche mit Text, Bild, Farbe, Video oder YouTube | | `@text` | `@text` | normaler Inhaltsbereich | | `@hinweis` | `@banner` | hervorgehobener Hinweis | | `@kacheln` | `@cards` | Kachelraster | | `@zwei-spalten` | `@two-columns` | zweispaltiger Bereich | | `@galerie` | `@gallery` | Bildergalerie mit vergroesserbarer Swipe-Ansicht | | `@zitat` | `@quote` | Zitatbereich | | `@zeitstrahl` | `@timeline` | Ablauf oder Zeitstrahl | | `@fragen` | `@faq` | Fragen-und-Antworten-Bereich | | `@kontakt` | `@contact` | Kontaktblock | | `@ort` | `@location` | Adresse mit OpenStreetMap-Link oder Karte | | `@bild-text` | `@image-text` | Bild links, Text rechts | | `@veranstaltung` | `@event` | einzelne Veranstaltungsbox | | `@veranstaltungen` | `@events` | Veranstaltungsliste | | `@dateien` | `@downloads` | Downloadliste | | `@person` | `@person` | einzelne Personenbox | | `@personen` | `@people` | Personen- oder Teamliste | | `@sponsoren` | `@sponsors` | Sponsor- oder Partnerlogos | ### Aufmacher ```md @aufmacher # Seitentitel Kurzer Einstiegstext. ``` Varianten: ```md @aufmacher:medien/galerie/Sommerfest/bild.jpg @aufmacher:medien/film.mp4 @aufmacher:https://www.youtube.com/watch?v=... @aufmacher:#1f6f78 ``` Ohne Zusatz bleibt der Aufmacherbereich so wie im Standard. ### Hinweis ```md @hinweis Anmeldung bis zum 1. Juli moeglich. ``` ### Kacheln ```md @kacheln:dreispaltig # Veranstaltungen ## Kon-Tiki Sommerregatta am Beetzsee. ## Inselcup Spassregatta. ``` Varianten: ```md @kacheln @kacheln:zweispaltig @kacheln:dreispaltig ``` Ohne Zusatz stehen die Kacheln untereinander. ### Fragen ```md @fragen # FAQ ## Wie melde ich mich an? Schreibe uns eine E-Mail. ## Wo finde ich den Verein? Die Adresse steht auf der Anfahrtsseite. ``` ### Veranstaltung ```md @veranstaltung # Sommerfest Datum: 12. Juli Uhrzeit: 15:00 Uhr Ort: Vereinsgelände Anmeldung: [Zur Anmeldung](https://example.com) ![Sommerfest](medien/galerie/Vereinsgelände/csm_db_blick_auf_grillhuette7_01_b8c05a4d5b.jpg) Gemeinsames Sommerfest mit Kuchen, Grill und kleinen Bootsrunden. ``` ### Veranstaltungen ```md @veranstaltungen # Termine ## Sommerfest Datum: 12. Juli Uhrzeit: 15:00 Uhr Ort: Vereinsgelände ![Sommerfest](medien/galerie/Vereinsgelände/csm_db_blick_auf_grillhuette7_01_b8c05a4d5b.jpg) Gemeinsames Sommerfest mit Kuchen, Grill und kleinen Bootsrunden. ## Absegeln Datum: 20. September Uhrzeit: 10:00 Uhr Ort: Vereinsgelände Gemeinsamer Saisonabschluss auf dem Wasser. ``` ### Dateien ```md @dateien # Downloads [Ausschreibung](medien/ausschreibung.pdf) [Anmeldung](https://example.com/anmeldung.pdf) ``` ### Personen ```md @person # Max Mustermann Vorsitzender max@example.de ``` ```md @personen # Team ## Max Mustermann Vorsitzender max@example.de ## Erika Beispiel Jugendwartin erika@example.de ``` ### Sponsoren ```md @sponsoren # Partner ![Sponsorname](medien/logo/sponsor.png) ``` ### Bild und Text ```md @bild-text ![Steg](medien/galerie/Vereinsgelände/csm_db_15er_steg27_01_41d2098b8f.jpg) # Unser Steg Hier steht der Text neben dem Bild. ``` ### Ort ```md @ort:Am Beetzsee 1, 14770 Brandenburg an der Havel # Anfahrt Hier steht ein kurzer Hinweis zur Anfahrt. ``` Wenn externe Inhalte erlaubt sind, wird OpenStreetMap eingebettet. Sonst zeigt der Block einen datenschutzfreundlichen Link zu OpenStreetMap. ## Interne Links Du kannst auf andere Seiten verlinken, indem du den Seitennamen in doppelte eckige Klammern setzt: ```md [[Impressum]] ``` Der Generator macht daraus automatisch den richtigen Link. Normale Markdown-Links funktionieren ebenfalls: ```md [Inselcupanmeldung](https://inselcup.msvb.de/) ``` ## Deployment Havelseiten baut lokal in den Ordner `ausgabe/`. Die Datei `.gitlab-ci.yml` zeigt einen einfachen GitLab-Pages-Deploy: GitLab installiert die Abhaengigkeiten, fuehrt den Generator aus und kopiert `ausgabe/` nach `public/`. Havelseiten selbst bleibt dadurch einfach; der Service entscheidet, wohin die fertigen Dateien veroeffentlicht werden. Geplanter Ausbau: - Galatea-UI fuer Upload und Bearbeitung ohne Terminal. - Einfacher Passwortschutz fuer geschuetzte Bereiche. ## Lizenz Havelseiten steht unter der MIT-Lizenz. Den vollstaendigen Lizenztext findest du in [LICENSE](LICENSE).