Meine Frau bloggt jetzt versioniert – und weiß nichts von Git

Meine Frau Sarah ist Traurednerin. Sie schreibt Texte, bei denen Menschen weinen, im guten Sinne. Ich bin ITler. Ich schreibe Systeme, bei denen niemand weinen soll. Und genau zwischen diesen beiden Welten stand jahrelang ein Prozess, der uns beiden auf die Nerven ging. Die Lösung ist am Ende ein Git-basiertes CMS für Nicht-Techniker geworden. Also ausgerechnet Git, das Werkzeug, von dem Sarah bis heute nichts merkt. Und das ist der eigentliche Trick an der Sache.

Aber der Reihe nach.

Das Problem waren nicht die Texte – es waren die Kommas

Sarahs Website lovelywords.eu ist ihre Seite. Ihre Sprache, ihre Persönlichkeit, ihr Ton. Und das ist der Punkt, an dem es früher regelmäßig knirschte: Sie schrieb einen Text, gab ihn mir, ich machte eine SEO-Optimierung drauf, und dann diskutierten wir. Nicht stundenlang, aber über einzelne Worte. Über Satzstellungen. Über ein Komma hier, eine Umstellung da.

Für mich war das völlig irrelevant. Für Sarah überhaupt nicht, weil es ihre Stimme ist, die da rausklingen soll. Und sie hat vollkommen recht damit. Wir hatten also einen kleinen, dauerhaften Interessenskonflikt: Ich wollte einen sauberen, schnellen Durchlauf, sie wollte ihre Formulierung. Und weil ich ihre Texte nicht selbst schreiben will (das ist ihr Job, nicht meiner), blieb ich das Nadelöhr. Jede Änderung lief über mich. Jedes Mal.

Ich habe dafür ehrlich gesagt weder Lust noch Zeit. Wenn ich bei jedem Wortdreher selbst Hand anlegen muss, staut sich das, und am Ende liegt ein fertiger Text tagelang rum, weil ich nicht dazukomme.

Die alte WordPress-Seite hat es nicht gelöst

„Dann gib ihr doch einfach WordPress“ – klar, hatten wir. Die ursprüngliche Seite lief auf WordPress. Theoretisch hätte Sarah dort ihre Texte selbst anpassen können.

Der Verzweiflung ganz nah

Hat sie nie gemacht.

Weil WordPress für ihren Fall schlicht zu viel war: zu langsam, zu groß, zu umständlich. Ein aufgeblähtes Backend mit tausend Optionen, Ladezeiten, Update-Gefrickel. Selbst mit Zugang hat sie es nicht angefasst, und ich konnte es ihr nicht mal verübeln. Wenn ein Werkzeug sich anfühlt wie Arbeit, benutzt man es nicht.

Die Lehre daraus war eindeutig: Was auch immer die neue Lösung wird, sie muss radikal einfach sein. So einfach, dass „ich pass den Text mal eben selbst an“ die naheliegende Option ist und nicht die, vor der man zurückschreckt.

Warum die Inhalte trotzdem Markdown bleiben mussten

Jetzt kommt meine Seite der Geschichte. Die neue lovelywords-Seite läuft auf Astro: schnell, schlank, statisch generiert. Die Blog-Beiträge liegen als Markdown-Dateien in einem Git-Repository, pro Beitrag ein Ordner mit Text und Bildern.

Das hat handfeste Gründe, an denen ich nicht rütteln wollte:

  • Versionierung. Jede Änderung ist nachvollziehbar und umkehrbar. Nichts geht verloren, nichts wird versehentlich überschrieben.
  • KI-Lesbarkeit. Sauberes Markdown ist das Format, das KI-Systeme und Suchmaschinen problemlos verstehen. Kein HTML-Wust, keine Datenbank-Blackbox, nur Struktur und Text.
  • Automatische Bild-Optimierung. Astro macht aus einem reingeworfenen Foto automatisch optimierte WebP/AVIF-Bilder in mehreren Größen. Schnelle Seite, kein Layout-Ruckeln, gutes SEO, ohne dass jemand von Hand etwas konvertiert.

DDer Haken: Genau dieses schöne, saubere Setup ist für einen Nicht-Techniker eine Wand. Markdown-Syntax, Frontmatter, Git-Commits, und iPhone-Fotos kommen auch noch als HEIC daher, ein Format, das im Web niemand direkt anzeigen kann. Von Sarah zu erwarten, dass sie Dateien auscheckt, committet und pusht, ist ungefähr so realistisch, wie wenn sie von mir verlangt, eine freie Trauung zu halten.

Ich brauchte also eine Oberfläche, die all das versteckt, ohne die Vorteile darunter aufzugeben.

Warum ich mich gegen ein CMS mit Datenbank entschieden habe

Die naheliegende Lösung wäre ein klassisches CMS mit Datenbank gewesen. Directus zum Beispiel, auf dem MySQL, das ohnehin schon läuft. Kann viel, moderner Editor, fertige Freigabe-Workflows.

Und trotzdem: nein. Ein Datenbank-CMS hätte mich aus der Git-Welt und aus der Astro-Bild-Pipeline geworfen und mich gezwungen, meine ganzen Markdown-Inhalte in eine Datenbank zu migrieren. Ich hätte den funktionierenden Kern meiner Architektur weggeworfen, um Komfort zu bekommen, den ich auch anders haben kann.

Also habe ich in die andere Richtung gesucht, zu einem Git-basierten CMS. Ein paar Kandidaten sind rausgeflogen (Keystatic kann kein GitLab, Decap wäre der Fallback, aber mit älterer Oberfläche, Eigenbau wollte ich mir nicht antun). Übrig blieb Sveltia CMS: eine schlanke Editor-Oberfläche, die Formularfelder auf Markdown-Frontmatter abbildet und das Ergebnis direkt als Commit in mein GitLab-Repo schreibt.

Endlich befreit Blogbeiträge schreiben

Das Schöne daran: Der Inhalt bleibt Markdown. Die Migration war praktisch null, weil die Inhalte ja schon im Zielformat lagen. Der Eingriff in meine bestehende Architektur ist minimal-invasiv, und genau das war mir wichtig.

Wie Sveltia CMS eigentlich funktioniert

Weil das der Punkt ist, an dem es für mich klick gemacht hat, hier etwas ausführlicher: Sveltia CMS ist der spirituelle Nachfolger von Netlify CMS bzw. dem heutigen Decap CMS, nur komplett in Svelte neu gebaut, schneller und mit einer Oberfläche, die sich nicht anfühlt wie aus 2016. Die Konfiguration ist dabei weitgehend kompatibel, ich hätte also später auch zurück auf Decap gekonnt. Wollte ich aber nicht.

Technik von Sveltia

Das Entscheidende ist die Architektur, denn sie ist herrlich unspektakulär: Sveltia ist kein Server und keine Datenbank, sondern eine einzige JavaScript-Datei. Eine Single-Page-App, die komplett im Browser läuft. Ich binde sie per <script>-Tag auf einer kleinen Seite ein, und das CMS liegt einfach unter einer eigenen Adresse neben dem Blog. Es gibt kein Backend, das ich betreiben, updaten oder absichern muss, nichts, was nachts umfällt oder gepatcht werden will.

Was das CMS anzeigt, steuere ich über eine einzige Konfigurationsdatei (config.yml). Darin beschreibe ich sogenannte Collections (für Sarah im Wesentlichen „Blogbeiträge“) und pro Collection die Felder, die sie im Editor sieht. Jedes Feld hat einen Typ, im Sveltia-Sprech ein Widget:

  • ein string-Widget wird zum simplen Titel-Eingabefeld,
  • ein markdown-Widget zum Rich-Text-Editor für den eigentlichen Beitrag (mit Fett, Kursiv, Überschriften, ohne dass Sarah ein einziges # oder ** sieht),
  • ein image-Widget zum Foto-Upload per Drag & Drop,
  • ein relation– bzw. select-Widget wird zur Auswahlliste. Genau darüber läuft später meine Orts-Auswahl statt GPS-Koordinaten.

Und hier passiert die eigentliche Magie: Sveltia übersetzt diese Formularfelder eins zu eins in Markdown mit YAML-Frontmatter, und wieder zurück. Was in der Datei als title:, date: oder description: im Frontmatter steht, sind exakt die Felder aus meiner Config; der Rich-Text darunter wird zum Markdown-Body. Sarah füllt ein Formular aus, heraus fällt genau die saubere Datei, die mein Astro-Build erwartet, kein Zwischenformat, keine Übersetzungsschicht, die irgendwann kaputtgeht.

Sveltia Gitlab Pipeline

Beim Speichern redet die JavaScript-App direkt mit der GitLab-API und schreibt einen ganz normalen Git-Commit auf den Branch, den ich in der Config festgelegt habe. Das Login läuft über OAuth mit Sarahs GitLab-Account: Sie klickt „Login“, autorisiert kurz bei GitLab und ist drin. Technisch hat sie damit einen echten Git-Zugang mit genau den Rechten, die ich vergebe. Nur nennt es niemand so. Für sie ist es „die Seite, auf der ich meine Beiträge schreibe“.

Kurz: Sveltia ist die dünne, hübsche Fassade vor meinem Git-Repo — es speichert nichts selbst, alles dahinter ist Git, das ich schon hatte.

Der eigentliche Trick: der Git-Flow ist der Freigabeprozess

Jetzt kommt der Teil, auf den ich ein bisschen stolz bin. Sveltia kennt keinen eingebauten Redaktions-Workflow, es arbeitet immer nur auf einem Branch. Statt das als Mangel zu sehen, habe ich es zum Kern des Konzepts gemacht: Der Redaktionsprozess ist einfach der ganz normale Git-Flow, nur ohne dass Sarah das je zu Gesicht bekommt.

Es gibt drei Branches mit klaren Rollen:

BranchWer schreibtWas passiert
redaktionSarah (über das CMS)Sammelbecken für Inhalte. Ein Speichern hier löst keinen Deploy aus.
integrationnur ichContent-Freigabe. Hier laufen automatisch die Tests und der Build.
mainnur ichDeploy-Freigabe. Ein Push hier ist der Auslöser für den Live-Gang.

Abgesichert wird das über Protected Branches in GitLab: Sarah darf ausschließlich nach redaktion schreiben, an integration und main kommt sie strukturell gar nicht ran. Es kann also nichts ungeprüft live gehen. Nicht weil wir uns zusammenreißen, sondern weil das System es nicht zulässt.

Der Merksatz, mit dem ich es Sarah erklärt habe: Du schreibst, ich gebe frei, der Rest passiert von allein.

Warum die Freigabe (noch) über mich läuft – und wohin die Reise geht

An dieser Stelle muss ich ehrlich sein: Dieser manuelle Freigabeschritt ist Absicht, aber nur für jetzt. Ich schaue aktuell bewusst noch einmal drüber, bevor etwas live geht. Nicht, um an Sarahs Formulierungen rumzudoktern (genau das will ich ja loswerden), sondern um harte Probleme abzufangen, bevor sie auf der Seite landen.

Denn ein paar Qualitätskriterien müssen einfach sitzen, bevor ein Beitrag online geht:

  • Die SEO-Felder müssen gefüllt sein: Titel, Beschreibung und Co.
  • Die Geo-Koordinaten müssen stimmen (dazu gleich mehr), weil falsche GPS-Daten falsches lokales SEO bedeuten.
  • Und das Ganze muss thematisch zusammenpassen.
Diskussionen über Kleinigkeiten

Das Spannende: Diese Prüfungen kann meine GitLab-CI größtenteils schon selbst erzeugen und validieren. Perspektivisch soll der Merge deshalb automatisch durch die Pipeline laufen. Sobald die Qualitäts-Gates grün sind, geht der Beitrag ohne mein Zutun live. Ich bin dann nicht mehr das Nadelöhr, sondern nur noch der, der die Regeln einmal definiert hat. Aktuell will ich einfach noch das Sicherheitsnetz meines eigenen Blicks behalten, bis ich den Automatiken hundertprozentig vertraue. Das ist für einen Blog völlig okay, ein paar Minuten Verzögerung tun niemandem weh.

Was Sarah davon merkt – nämlich fast nichts

Und so sieht Sarahs Alltag heute aus: Sie öffnet die Oberfläche im Browser, loggt sich ein, schreibt ihren Beitrag wie in einem ganz normalen Texteditor, zieht ein Foto rein, tippt einen Alt-Text dazu und klickt auf Speichern. Fertig.

Kein Markdown. Kein Git. Kein Commit. Keine Bildkonvertierung.

Dahinter arbeiten ein paar Automatiken, die früher meine Handarbeit waren:

  • Bilder aufbereiten. iPhone-Fotos kommen als HEIC, ein CI-Job konvertiert sie automatisch nach JPEG, schreibt die Referenzen im Text um und setzt die EXIF-Daten (Copyright, Bildbeschreibung aus dem Alt-Text, GPS aus der Location). Sarah muss am Bildformat nichts tun.
  • Orte per Auswahl statt Koordinaten. Damit sie keine GPS-Zahlen eintippen muss, gibt es eine zentrale Orts-Liste. Sarah wählt einfach „Weingut XY“ aus, und daraus entstehen automatisch die ganzen Geo-Signale der Seite. Findet sie keinen passenden Ort, lässt sie das Feld leer, den Rest pflege ich später nach.

Ein netter Nebeneffekt der Architektur: Das CMS ist nur aus unserem Heimnetz erreichbar. Keine Cloud, kein öffentlicher Zugang, die Angriffsfläche geht damit gegen null.

Was mich der Weg gekostet hat

Damit hier kein Hochglanz-Bild entsteht: Umsonst gab es das nicht.

  • Veröffentlichen ist nicht sofort. Der Weg über die drei Branches und die Pipeline dauert ein paar Minuten. Geschenkt.
  • Die Ersteinrichtung war fummelig. OAuth-App, und dann die HTTPS-Geschichte: Sveltia will zwingend eine sichere Verbindung, selbst im Heimnetz. Das über lokal vertrauenswürdige Zertifikate auf allen Geräten hinzubekommen, hat mich ein paar Nerven gekostet.
  • Keine echte Vorschau vor dem Merge. Die Vorschau im CMS ist nur ungefähr, wie es final aussieht, sehe ich erst beim Freigeben. Ein Staging-Container wäre möglich, den habe ich mir bewusst für später aufgehoben.

Aber diesen Kompromissen steht der eine große Gewinn gegenüber: Sarah kann endlich selbst bloggen, ich behalte meine saubere, versionierte, KI-lesbare Architektur, und der Streit über die Kommas findet gar nicht mehr statt, weil sie ihre Texte direkt selbst tippt und ändert.

Was ich daraus mitnehme

Die beste Lösung war am Ende nicht die technisch mächtigste. Directus hätte „mehr gekonnt“. Die beste Lösung war die, die niemandem etwas abverlangt, was er nicht will: Sarah muss nichts von Technik verstehen, und ich muss ihre Texte nicht anfassen. Jeder bleibt in seiner Welt, und die Brücke dazwischen läuft von allein.

Das ist übrigens ein Muster, das sich durch fast alle meine Projekte zieht, von der SmileCube Fotobox bis zum Pool: Ich baue am liebsten Dinge, die eine lästige Handarbeit unsichtbar wegautomatisieren. Nicht das größte System gewinnt, sondern das, das man am Ende auch wirklich benutzt.

Und der beste Beweis, dass es funktioniert: Sarah bloggt inzwischen, ohne mich zu fragen. Von Git hat sie noch immer nichts gehört. Genau so soll es sein.

Übrigens: Die Bilder in diesem Beitrag sind natürlich alle mit KI erstellt – der Text aber nicht, den hab ich noch selbst getippt. Passt ja irgendwie zum Thema.

This article was written by Thomas Schiffler

Ich bin Thomas Schiffler – Softwareentwickler und IT-Architekt. Beruflich beschäftige ich mich intensiv mit dem sinnvollen Einsatz von KI-Agenten in der Produkt- und Anforderungsarbeit – als Verstärkung, die den Menschen unterstützt, statt ihn zu ersetzen. Privat gilt meine Begeisterung Smart-Home-Automatisierung, Raspberry-Pi-Projekten und allem, was den Alltag smarter macht. Auf schiffler.eu teile ich meine Erfahrungen, Ideen und Experimente aus beiden Welten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert