# 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 havelseiten build`.

## Seite bauen

```sh
python3 havelseiten build
```

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 havelseiten validate
```

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.

## Einstellungen formatieren

```sh
python3 havelseiten format
```

Der Formatter bringt `havelseite/einstellungen.md` in eine saubere Form. Aus `- [] Wald` wird zum Beispiel `- [ ] Wald`.

## 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).
