CMF Anleitung

Vom Login bis zur fertigen Seite. Alles, was du zum Arbeiten mit dem CMF brauchst.

Über diese Anleitung

Dieses CMS funktioniert ohne Datenbank, ohne Build-Tool und ohne technisches Vorwissen. Inhalte werden als strukturierte Blöcke gepflegt – über den visuellen Block-Editor oder direkt als JSON.

Vom Login bis zur fertigen Seite, vom Textblock bis zur Spaltenstruktur – alles auf einer Seite.

Inhalt

  1. Erste Schritte
  2. Seitenstruktur
  3. Blocktypen
  4. Spalten und HTML
  5. Medien
  6. Navigation und globale Bereiche
  7. Theme und Custom CSS
  8. Blog
  9. Backup und Import
  10. Regeln und Validierung
  11. FAQ

1. Erste Schritte

Backend: Seitenübersicht mit Status und Aktionen
Die Seitenübersicht mit allen Seiten, Status und Aktionen.
Backend: Neue Seite anlegen mit Formularfeldern
Eine neue Seite: Titel, Slug, Status, Navigation und Block-Editor.

Login

Das Backend erreichst du unter /admin.php. Benutzername und Passwort werden beim Einrichten festgelegt.

Nach dem Login siehst du die Seitenübersicht mit allen Seiten, ihrem Status und den Aktionen Bearbeiten, Duplizieren und Löschen.

Tipp: Unter Benutzer kann das Passwort jederzeit geändert werden.

Backend-Bereiche

  • Seiten – Inhalte erstellen und bearbeiten
  • Blog – Blogbeiträge verwalten
  • Header/Footer – globale Bereiche
  • Theme – Farben, Schriften, Custom CSS
  • Media – Bilder und Dateien
  • Benutzer – Zugänge verwalten
  • Einstellungen – Backup, Import

Erste Seite

  1. Seiten > Neue Seite
  2. Titel und Slug festlegen
  3. + Heading für Überschrift
  4. + Text für einen Absatz
  5. Status auf published setzen
  6. Speichern

2. Seitenstruktur

Inhaltsobjekt (JSON)

Jede Seite besteht intern aus zwei Teilen:

{
  "meta": {
    "title": "Seitentitel",
    "description": "Kurzbeschreibung"
  },
  "content": {
    "blocks": [
      { "id": "h1_start", "type": "heading", "data": {...} },
      { "id": "t1_intro", "type": "text", "data": {...} }
    ]
  }
}

meta.title ist Pflicht. content.blocks enthält die geordnete Liste aller Inhaltsblöcke.

Seitenobjekt (Verwaltung)

Getrennt vom Inhalt verwaltet das System diese Felder:

  • id – interne Seiten-ID
  • slug – URL-Teil (z.B. kontakt/kontakt)
  • title – Seitenname
  • statusdraft oder published
  • nav.show – im Menue anzeigen
  • nav.order – Sortierung (kleiner = weiter links)
  • nav.label – optionaler Menütext
  • nav.parent – Seiten-ID für Untermenüs

Im Backend stehen diese Felder oberhalb des Editors. Der Slug home wird automatisch zur Startseite.

Tipp: Die Seiten-ID für Untermenüs findest du in der Seitenübersicht – sie steht klein unter dem Seitentitel.

3. Blocktypen

Backend: Seiten-Editor mit Formularfeldern und Block-Toolbar
Der Seiten-Editor mit Seiteneinstellungen und Block-Editor.
Backend: Block-Toolbar und Editor-Blöcke mit Aktionen
Toolbar-Buttons, Block-Editor/JSON-Umschalter und Blöcke mit Aktionen.

Jeder Block hat drei Felder: id (eindeutig pro Seite), type und data. Im Editor werden Blöcke über die Toolbar angelegt: + Heading, + Text, + Bild, + Liste, + Buttons, + Spalten, + HTML und + Blog Übersicht. Zwischen Block-Editor und JSON-Ansicht kann jederzeit umgeschaltet werden.

heading

Überschriften von h1 bis h6.

{ "level": 1, "text": "Überschrift" }

Pro Seite genau ein h1, danach logisch mit h2, h3 weiterarbeiten.

text

HTML-Textblock für Absätze und Formatierungen.

{ "html": "<p>Ein Absatz</p>" }

Erlaubte Tags: p, br, strong, em, u, a, ul, ol, li, code, pre, span, small, sup, sub.

image

Bild mit optionaler Bildunterschrift.

{ "src": "/media/2026/03/bild.jpg",
  "alt": "Beschreibung",
  "caption": "Optional",
  "loading": "lazy" }

src und alt sind Pflicht. Im Editor: Bild auswählen übernimmt ein hochgeladenes Medium direkt.

list

Einfache Aufzählung oder nummerierte Liste.

{ "ordered": false,
  "items": ["Punkt 1", "Punkt 2"] }

ordered: true = nummeriert. Einträge sind einfache Strings.

buttons

Verlinkte Buttons für Call-to-Actions.

{ "items": [
  { "label": "Mehr", "href": "/seite",
    "style": "primary" }
] }

label und href sind Pflicht.

blog_overview

Rendert das Blog-Karten-Grid automatisch.

{ "category": "" }

Leer = alle Beiträge. Mit Kategorie wird gefiltert.

4. Spalten und HTML

columns

Strukturblock mit 2–5 Spalten. Jede Spalte enthält normale Blöcke.

{ "columns": 3,
  "items": [
    [{ "id": "h3_a", "type": "heading", "data": {...} }],
    [{ "id": "t_b", "type": "text", "data": {...} }],
    [{ "id": "b_c", "type": "buttons", "data": {...} }]
  ] }

items muss exakt so viele Arrays enthalten wie columns angibt. IDs der Unterblöcke müssen global eindeutig sein.

Tipp: Im Editor legst du die Spaltenzahl fest. Jede Spalte hat dann einen eigenen Bereich, in den du Blöcke einfügen kannst. Auf kleinen Bildschirmen werden die Spalten automatisch untereinander dargestellt.

html

Der mächtigste Blocktyp: freier HTML-Code, der direkt ausgegeben wird – ohne Einschränkungen und ohne Sanitizing.

{ "code": "<div class=\"card\">Inhalt</div>" }

Damit lässt sich praktisch alles umsetzen, was mit den anderen Blocktypen nicht möglich ist:

  • Layouts – Karten, Grids, Flex-Bereiche, individuelle Abschnitte
  • Embeds – Videos (YouTube, Vimeo), Karten, Podcasts, Social Media
  • Formulare – Kontaktformulare, Newsletter-Anmeldungen
  • Tabellen – strukturierte Daten in <table>
  • Interaktives – Akkordeons, Tabs, Countdowns per inline <script>
  • Gestaltung – Hero-Banner, Statistiken, Zeitleisten, Zitate

Tipp: Eigene CSS-Klassen unter Theme → Custom CSS definieren und hier per class="..." verwenden – statt Inline-Styles. So bleibt der Code sauber und wiederverwendbar.

Beispiel: So sieht ein 5-spaltiger columns-Block aus:

Spalte 1

In jeder Spalte dürfen normale Blöcke liegen: Überschriften, Text, Listen, Bilder oder Buttons.

Die Spalten passen sich auf kleinen Bildschirmen automatisch untereinander an – von fünf nebeneinander bis zu einer einzigen Spalte auf dem Smartphone.

Spalten eignen sich besonders für Vergleiche, Feature-Listen oder Inhalte, die nebeneinander besser wirken als untereinander.

Spalte 2

Efeu

Spalte 3

Buttons funktionieren auch innerhalb von Spalten. So entstehen kompakte Call-to-Action-Bereiche direkt neben erklärendem Text oder Bildern.

Der Style primary hebt den Button farblich hervor. Ohne Style wird er dezent dargestellt.

Zum Kontakt

Spalte 4

Normale Textblöcke zeigen, dass auch längere Absätze in schmalen Spalten gut lesbar bleiben.

Das System bricht den Text automatisch um. Schriftgröße und Zeilenabstand werden vom Theme gesteuert – hier muss nichts manuell angepasst werden.

  • Listen in Spalten
  • Funktionieren genauso
  • Wie außerhalb

Spalte 5

HTML-Block

Auch freier HTML-Code ist in Spalten möglich. Hier als Beispiel eine Card-Fläche mit eigenem Layout – per class="card" gestaltet.

5. Medien

Backend: Media-Übersicht mit Thumbnails und Einbindungen
Media-Übersicht: Thumbnails, Dateigröße, Einbindungen und Sperrung.
Backend: Theme-Editor mit Farben, Layout und Schriftgrößen
Der Theme-Editor: Layout, Ecken, Farben mit Color-Pickern.

Hochladen

Im Backend unter Media können Dateien per Drag & Drop oder Dateiauswahl hochgeladen werden. Uploads landen automatisch unter /media/YYYY/MM/. Bei doppelten Dateinamen wird automatisch ein eindeutiger Name erzeugt.

Erlaubte Typen: jpg, png, webp, gif, svg, pdf, mp4, mp3, wav.

Tipp: Bilder werden beim Upload nicht verkleinert. Für schnelle Ladezeiten empfiehlt sich, Bilder vorher auf die benötigte Größe zu bringen.

Einbinden

Im Bildblock gibt es die Schaltfläche Bild auswählen. Damit wird ein hochgeladenes Bild direkt übernommen – kein Pfad manuell eintippen.

Im JSON wird der Pfad als src im image-Block verwendet:

"src": "/media/2026/03/bild.jpg"

Löschen

In der Media-Übersicht zeigt jede Datei ihre Einbindungen – also wo sie auf Seiten oder in Blog-Posts verwendet wird.

Eingebundene Medien sind gesperrt und können nicht gelöscht werden. Nur Dateien ohne Einbindung zeigen einen Löschen-Button.

Über Auf Einbindung prüfen wird die Zuordnung aller Medien aktualisiert.

6. Navigation und globale Bereiche

Navigation

Die Navigation wird automatisch aus allen veröffentlichten Seiten erzeugt:

  • Nur Seiten mit status: published und nav.show: true
  • Sortiert nach nav.order (kleinere Zahl = weiter links)
  • nav.label überschreibt den Menü-Text
  • nav.parent mit einer Seiten-ID erzeugt ein Untermenü (Klappmenü)

Tipp: Die Seite mit dem Slug home wird als Startseite unter / angezeigt. Seiten mit nav.show: false sind erreichbar, aber nicht im Menü sichtbar.

Header und Footer

Header und Footer verwenden das gleiche Block-Schema wie Seiten. Sie werden global auf allen Seiten angezeigt.

Im Backend unter Header/Footer bearbeiten. Zwischen Block-Editor und JSON umschalten funktioniert wie bei normalen Seiten.

7. Theme und Custom CSS

Theme-Konfiguration

Im Backend unter Theme wird das Design als JSON konfiguriert: Container, Abstände, Farben, Schriftgrößen und Schriften.

Farben: Hex-Werte im colors-Objekt. primary = Akzentfarbe für Buttons/Links.

Schriften: Fontname unter fonts.body / fonts.heading eintragen (Teil vor dem Bindestrich im Dateinamen). Gewicht: light, regular oder bold.

Nach dem Speichern ist die CSS sofort aktiv – kein Build-Schritt nötig.

Tipp: Verfügbare Fonts werden unterhalb des Theme-Editors angezeigt. 10 Schriftfamilien mit je 3 Schnitten (Light, Regular, Bold) sind vorinstalliert.

Custom CSS

Unter Theme → Custom CSS kann eigenes CSS geschrieben werden. Die Datei wird nach theme.css geladen und kann alles überschreiben oder ergänzen.

Eigene Klassen dort definieren und dann in html-Blöcken per class="..." verwenden – statt Inline-Styles.

8. Blog

Backend: Blog-Beitragsliste und Einstellungen
Blog-Verwaltung: Beitragsliste und Einstellungen (URL-Prefix, Kategorien).
Backend: Blog-Post-Editor mit Kategorie, Bild und Beschreibung
Blog-Post-Editor: Titel, Kategorie, Bild-Pfad, Beschreibung und Block-Editor.

Das CMF enthält ein integriertes Blog-System. Blogbeiträge werden als eigener Inhaltstyp verwaltet – getrennt von Seiten, aber mit dem gleichen Block-Editor. Der Blog hat im Backend einen eigenen Bereich mit Beitragsliste, Einstellungen und Drag-and-Drop-Sortierung.

Beiträge erstellen

Im Backend unter Blog findest du die Beitragsliste. Über + Neuer Beitrag wird ein neuer Post angelegt.

Jeder Beitrag hat diese Felder:

  • Titel – Name des Beitrags
  • Slug – URL-Teil (wird aus dem Titel generiert)
  • Statusdraft oder published
  • Kategorie – aus den definierten Kategorien wählbar
  • Bild-Pfad – Vorschaubild für die Übersicht
  • Beschreibung – Kurztext für die Karten-Vorschau

Der eigentliche Inhalt wird darunter im Block-Editor gepflegt – genau wie bei normalen Seiten.

Verwaltung und Einstellungen

Reihenfolge: In der Beitragsliste können Posts per Drag-and-Drop umsortiert werden. Die Reihenfolge bestimmt die Anzeige auf der Übersichtsseite.

Duplizieren: Jeder Beitrag kann über den Button Duplizieren kopiert werden – praktisch für ähnliche Inhalte.

Blog-Einstellungen stehen unterhalb der Beitragsliste:

  • Blog-URL-Prefix – bestimmt die URL-Struktur. Standard ist blog, kann aber geändert werden (z.B. news). Beiträge sind dann unter /news/beitrag-slug erreichbar.
  • Kategorien – kommagetrennt eingeben (z.B. Neuigkeiten, Tutorials, Updates). Diese stehen dann beim Erstellen eines Beitrags als Dropdown zur Verfügung.

Im Frontend

Die Blog-Übersicht zeigt alle veröffentlichten Beiträge als Karten-Grid. Jede Karte zeigt das Beitragsbild, den Titel und die Beschreibung. Das Layout ist responsiv (5/4/3/2/1 Spalten je nach Bildschirmbreite).

Blog-Seite einrichten: Die Blog-Übersicht ist eine normale Seite mit einem blog_overview-Block. Dieser Block rendert das Karten-Grid automatisch. Optional kann über category nach einer Kategorie gefiltert werden.

Einzelne Posts sind unter /prefix/post-slug erreichbar (z.B. /news/mein-beitrag). Der Prefix wird in den Blog-Einstellungen festgelegt.

Hinweis: Blogbeiträge erscheinen nicht in der Navigation – sie sind ausschließlich über die Übersichtsseite und direkte Links erreichbar.

9. Backup und Import

Backend: Einstellungen mit System-Update, Export und Import
Einstellungen: Versionsprüfung, ZIP-Export und ZIP-Import.
Backend: Seitenhierarchie mit Unterseiten
Seitenhierarchie: Unterseiten werden eingerückt dargestellt.

Unter Einstellungen findest du Export, Import und die Versionsprüfung. Damit lassen sich Webseiten sichern, zwischen Servern verschieben oder Vorlagen verteilen.

Export

Erstellt ein ZIP-Backup der Webseite. Per Checkboxen wählst du aus, was enthalten sein soll:

  • Header – globaler Header-Inhalt
  • Footer – globaler Footer-Inhalt
  • Seiten – alle Seiten mit Seitenindex
  • Medien – alle hochgeladenen Dateien

Nach dem Klick auf ZIP exportieren wird die Datei als cmf-backup-YYYY-MM-DD.zip heruntergeladen.

Tipp: Regelmäßige Backups vor größeren Änderungen schützen vor Datenverlust.

Import

Der Import läuft in zwei Schritten:

  1. ZIP analysieren – ZIP-Datei hochladen. Das System zeigt den Inhalt: Anzahl Seiten (mit Titeln), Medien, Header/Footer.
  2. Import starten – per Checkboxen wählen, was importiert werden soll. Dann bestätigen.

Wichtig: Vorhandene Seiten werden aktualisiert (gleiche ID), neue Seiten erstellt. Es wird nichts gelöscht. Medien werden in die bestehende Ordnerstruktur kopiert.

System-Update

Oben auf der Einstellungsseite wird die installierte Version mit der verfügbaren Version verglichen.

Wenn ein Update bereitsteht, kann es direkt aus dem Backend heruntergeladen und eingespielt werden. Die eigenen Inhalte, Medien und Konfiguration bleiben dabei erhalten – nur der Systemcode wird aktualisiert.

10. Regeln und Validierung

Inhaltsregeln

  • Pro Seite genau ein h1
  • Logische Überschriftenhierarchie (h2, h3, ...)
  • Block-IDs sprechend und stabil halten
  • Bilder immer mit Alt-Text
  • Im text-Block nur sauberes HTML
  • html-Block nur für Sonderfälle
Anleitung fürs Internet

Validierung

  • meta.title darf nicht leer sein
  • content.blocks muss ein Array sein
  • Jeder Block braucht id, type und data
  • IDs müssen eindeutig sein (auch in Spalten)
  • Nur bekannte Blocktypen erlaubt
  • columns.items = exakte Spaltenzahl
  • image: src und alt Pflicht
  • buttons: label und href Pflicht

11. FAQ

Seiten und Inhalte

Wie veröffentliche ich eine Seite?
Status auf published setzen und speichern. Seiten mit draft sind nur im Backend sichtbar.

Wie erstelle ich ein Untermenü?
Im Seitenformular bei Unterpunkt von die Seiten-ID der Elternseite eintragen.

Muss jede Seite ein h1 haben?
Ja, genau ein inhaltliches h1 pro Seite. Danach logisch mit h2, h3 weiterarbeiten.

Darf ich freie Felder im JSON ergänzen?
Nein. Unbekannte Felder werden ignoriert. Das Schema ist bewusst klein gehalten.

Block-Editor

Wie lösche ich einen Block?
Über das Löschen-Symbol am Block. Es gibt kein Undo.

Wie verschiebe ich einen Block?
Über die Pfeil-Schaltflächen am Block nach oben oder unten.

Kann ich zwischen Editor und JSON wechseln?
Ja – über die Umschalter oben auf der Seite. Änderungen werden beim Wechsel übernommen.

Ersetzt der Editor das JSON?
Nein. Er ist die Eingabeoberfläche – gespeichert wird immer JSON.

Medien und Theme

Wie lade ich Bilder hoch?
Media → Dateiauswahl oder Drag & Drop. Dann im Bildblock über Bild auswählen einbinden.

Wie ändere ich die Schrift?
Theme → fonts.body oder fonts.heading auf den Fontnamen setzen. Gewicht: light, regular oder bold.

Wie ändere ich Farben?
Theme → im colors-Objekt die Hex-Werte anpassen. primary ist die Akzentfarbe für Buttons und Links.

Kann ich eigenes CSS schreiben?
Ja. Unter Theme → Custom CSS. Eigene Klassen definieren und per class="..." in html-Blöcken verwenden.