iToverDose/Software· 4 MAI 2026 · 05:38

Markdown zu CMS: Automatisierte Veröffentlichung mit GitHub Actions

Verabschiede dich von manuellen CMS-Veröffentlichungen! Erfahren Sie, wie eine automatisierte Pipeline mit GitHub Actions Ihre Markdown-Inhalte in WordPress, Ghost oder Webflow in unter 90 Sekunden live schaltet – effizient, konsistent und ohne manuelle Formatierung.

DEV Community5 min0 Kommentare

Die traditionelle Veröffentlichung von Inhalten folgt oft einem ineffizienten Dreiklang: Text schreiben, CMS öffnen, formatieren, einfügen und schließlich veröffentlichen. Für einzelne Artikel mag das akzeptabel sein – doch für Teams, die monatlich Dutzende Beiträge publizieren, wird daraus ein stiller Zeitfresser.

Eine automatisierte Lösung mit GitHub Actions kann diesen Prozess komplett revolutionieren. Statt manueller Schritte überträgt ein einfaches Commit eines .md-Files direkt in ein CMS – sei es WordPress, Ghost oder Webflow. Innerhalb von maximal 90 Sekunden erscheint der Artikel online, formatiert, getaggt und bereit für die Leserschaft. Hier erfahren Sie, wie Sie diese Automatisierung aufbauen und welche Fallstricke Sie dabei vermeiden müssen.

Der Workflow im Überblick

Am Ende dieser Anleitung haben Sie eine voll funktionsfähige Pipeline, die folgende Komponenten umfasst:

  • Ein Git-Repository als einzige Quelle für Ihre Inhalte
  • Eine GitHub-Actions-Workflow-Datei, die bei jedem Push auf den main-Branch ausgelöst wird
  • Ein Node.js-Skript, das Frontmatter ausliest, Markdown verarbeitet und die Inhalte per API an Ihr CMS übermittelt
  • Unterstützung für WordPress (REST-API), Ghost (Admin-API) und Webflow (CMS-API) – wahlweise einzeln oder kombiniert
  • Separate Branches für Entwürfe (Staging) und finale Veröffentlichungen (Main)

Die finale Ordnerstruktur sieht wie folgt aus:

content-pipeline/
├── .github/
│   └── workflows/
│       └── publish.yml
├── posts/
│   ├── mein-erster-beitrag.md
│   └── ein-zweiter-beitrag.md
├── scripts/
│   ├── publish.js
│   ├── publishers/
│   │   ├── wordpress.js
│   │   ├── ghost.js
│   │   └── webflow.js
│   └── utils/
│       ├── parse-frontmatter.js
│       └── transform-markdown.js
├── package.json
└── .env.example

Warum die Umsetzung komplexer ist als gedacht

Die naheliegende Idee – einfach den Markdown-Text an die CMS-API zu senden – scheitert in der Praxis an drei zentralen Herausforderungen:

  • Formatkonflikte: CMS-Systeme akzeptieren keinen reinen Markdown-Text. WordPress erwartet HTML, Ghost verwendet ein eigenes Lexical-Editor-Format für komplexe Inhalte, und Webflow verlangt strukturierte JSON-Daten mit spezifischen Rich-Text-Feld-Schemata.
  • Frontmatter als Metadaten-Kontrakt: Die Zuordnung von Metadaten wie Tags oder Status variiert stark zwischen den Systemen. In Ghost sind Tags als Array von Tag-Objekten definiert, in WordPress müssen Tags zunächst in IDs aufgelöst werden, und Webflow kennt keine klassischen Tags – stattdessen kommen benutzerdefinierte Feld-Slugs zum Einsatz.
  • Idempotenz: Ein versehentlich doppelt ausgelöster Workflow darf nicht zu doppelten Artikeln führen. Eine zuverlässige Lösung erfordert eine Abfrage vor jedem Publish, um zu entscheiden, ob ein neuer Artikel erstellt oder ein bestehender aktualisiert wird.

Diese Hürden sind keine Randfälle, sondern treten bereits beim ersten echten Publish auf. Das folgende Skript berücksichtigt alle drei Problemstellungen.

Voraussetzungen für die Umsetzung

Bevor Sie mit der Implementierung beginnen, stellen Sie sicher, dass folgende Grundlagen erfüllt sind:

  • Node.js in Version 18 oder höher
  • Ein GitHub-Repository (auch kostenlose Konten sind ausreichend)
  • Zugang zu mindestens einem der unterstützten CMS:
  • WordPress mit aktivierten Application Passwords
  • Ghost mit Admin-API-Zugriff
  • Webflow mit einer CMS-Collection
  • Grundlegende Kenntnisse der GitHub-Actions-Syntax

Schritt 1: Der Frontmatter-Kontrakt definieren

Jeder Beitrag benötigt einen konsistenten Frontmatter-Block am Anfang der Markdown-Datei. Dieses Metadaten-Fragment dient als zentrale Steuerungsinstanz für den Publish-Prozess.

---
title: "Mein Artikel-Titel"
slug: "mein-artikel-titel"
description: "Ein Satz Zusammenfassung für Meta-Beschreibungen und CMS-Auszüge."
tags: ["javascript", "devops", "tutorial"]
status: "published"  # oder "draft"
targets: ["wordpress", "ghost"]  # Welche CMS-Systeme ansteuern?
date: "2025-01-15"
cover_image: "
---

Der targets-Parameter ist dabei besonders wichtig. Er ermöglicht es, dass ein einzelnes Repository unterschiedliche CMS-Systeme ansteuert. Ein Marketing-Beitrag könnte beispielsweise nur WordPress ansprechen, während ein technischer Deep-Dive auch Ghost erreicht. Das Skript wertet diese Liste aus und leitet die Inhalte entsprechend weiter.

Schritt 2: Frontmatter parsen und Markdown transformieren

Ein zentraler Baustein ist das Parsen des Frontmatter und die Umwandlung des Markdown-Inhalts in das benötigte Format. Hier ein Beispiel-Parser:

// scripts/utils/parse-frontmatter.js
import fs from 'fs';
import matter from 'gray-matter';
import { marked } from 'marked';

export function parsePost(filePath) {
  const raw = fs.readFileSync(filePath, 'utf-8');
  const { data: frontmatter, content } = matter(raw);

  // Überprüfen, ob alle Pflichtfelder vorhanden sind
  const required = ['title', 'slug', 'targets'];
  const missing = required.filter(field => !frontmatter[field]);
  if (missing.length > 0) {
    throw new Error(`Fehlende Pflichtfelder im Frontmatter: ${missing.join(', ')} in ${filePath}`);
  }

  return {
    frontmatter,
    markdown: content,
    html: marked(content),  // WordPress benötigt HTML
    filePath,
  };
}

Zwei wichtige Details:

  • Die Bibliothek gray-matter ist der Standard für das Parsen von Frontmatter in Markdown – stabil, weit verbreitet und zuverlässig.
  • Die Markdown-Inhalte werden bereits beim Parsen in HTML umgewandelt. So stehen allen Publisher-Skripten beide Formate zur Verfügung, und jedes System kann die passende Darstellung wählen.

Installieren Sie die benötigten Abhängigkeiten mit:

npm install gray-matter marked

Schritt 3: Integration mit WordPress

WordPress bietet zwar die ausgereifteste API der drei unterstützten Systeme, verlangt aber besondere Aufmerksamkeit bei der Tag-Verwaltung. Tags können nicht einfach als Namen übergeben werden – stattdessen müssen sie zunächst in IDs aufgelöst werden. Falls ein Tag noch nicht existiert, wird er automatisch angelegt.

// scripts/publishers/wordpress.js
const WP_BASE = process.env.WP_BASE_URL;  // z.B. 
const WP_USER = process.env.WP_USERNAME;
const WP_PASS = process.env.WP_APP_PASSWORD;  // Application Password

const authHeader = 'Basic ' + Buffer.from(`${WP_USER}:${WP_PASS}`).toString('base64');

async function resolveTagIds(tagNames) {
  const ids = [];
  for (const name of tagNames) {
    // Prüfen, ob der Tag bereits existiert
    const searchRes = await fetch(
      `${WP_BASE}/wp-json/wp/v2/tags?search=${encodeURIComponent(name)}`,
      { headers: { Authorization: authHeader } }
    );
    const existing = await searchRes.json();

    if (existing.length > 0) {
      ids.push(existing[0].id);
    } else {
      // Tag neu anlegen
      const createRes = await fetch(`${WP_BASE}/wp-json/wp/v2/tags`, {
        method: 'POST',
        headers: {
          Authorization: authHeader,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name }),
      });
      const newTag = await createRes.json();
      ids.push(newTag.id);
    }
  }
  return ids;
}

export async function publishToWordPress({ frontmatter, html }) {
  const tagIds = await resolveTagIds(frontmatter.tags ?? []);

  // Prüfen, ob der Artikel bereits existiert (Idempotenz)
  const slugCheckRes = await fetch(
    `${WP_BASE}/wp-json/wp/v2/posts?slug=${frontmatter.slug}`,
    { headers: { Authorization: authHeader } }
  );
  const existing = await slugCheckRes.json();

Die Idempotenz-Prüfung stellt sicher, dass ein versehentlich doppelt ausgelöster Workflow nicht zu doppelten Artikeln führt. Das System erkennt anhand des Slugs, ob ein neuer Artikel erstellt oder ein bestehender aktualisiert werden muss.

Mit dieser Pipeline können Sie Ihre Markdown-Inhalte effizient und ohne manuelle Formatierungsarbeit in WordPress, Ghost oder Webflow veröffentlichen. Die Automatisierung spart nicht nur Zeit, sondern reduziert auch menschliche Fehler und sorgt für eine konsistente Darstellung Ihrer Inhalte.

Für Teams, die regelmäßig Inhalte produzieren, ist diese Lösung ein Game-Changer – doch der größte Nutzen liegt in der Freiheit, sich auf das Wesentliche zu konzentrieren: großartige Inhalte zu schreiben, statt sie manuell zu veröffentlichen.

KI-Zusammenfassung

GitHub Actions ile birlikte Markdown dosyalarınızı CMS'ye otomatik olarak yayınlayabileceğiniz bir sistem oluşturabilirsiniz. Bu sistem, WordPress, Ghost ve Webflow gibi platformları desteklemektedir.

Kommentare

00
KOMMENTAR SCHREIBEN
ID #KSG1HY

0 / 1200 ZEICHEN

Menschen-Check

3 + 6 = ?

Erscheint nach redaktioneller Prüfung

Moderation · Spam-Schutz aktiv

Noch keine Kommentare. Sei der erste.