{"id":413,"date":"2026-10-03T17:10:40","date_gmt":"2026-10-03T17:10:40","guid":{"rendered":"https:\/\/www.fabricioruch.ch\/?p=413"},"modified":"2026-10-03T17:14:24","modified_gmt":"2026-10-03T17:14:24","slug":"markdown-entwuerfe-wordpress-ohne-block-editor","status":"publish","type":"post","link":"https:\/\/www.fabricioruch.ch\/?p=413","title":{"rendered":"Technische Artikel ohne Block-Editor: Markdown, Git und WordPress-Entw\u00fcrfe"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Wenn du diesen Blog liest, siehst du am Ende nur eine <strong>normale WordPress-Seite<\/strong>: Titel, Kategorien, Leselayout, manchmal Code mit Syntax-Farben. Was du <strong>nicht<\/strong> siehst, ist <em>wie<\/em> der Text entstanden. F&#252;r die meisten Beitr&#228;ge gilt weiterhin: Autor &#246;ffnet WordPress im Browser, schreibt im <strong>Block-Editor<\/strong> (Gutenberg), setzt ein Titelbild, klickt auf Ver&#246;ffentlichen.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">F&#252;r <strong>technische Field Notes<\/strong> und alles, was ich mit <strong>Git<\/strong>, <strong>Terminal<\/strong> oder <strong>KI-Assistenten<\/strong> vorbereite, nutze ich einen zweiten Weg: Der Artikel lebt zuerst als <strong>Textdatei<\/strong> auf meinem Rechner (Markdown), wird per Skript als <strong>Entwurf<\/strong> nach WordPress geschickt, und erst dort schaue ich noch einmal dr&#252;ber und ver&#246;ffentliche manuell. Dieser Beitrag erkl&#228;rt diesen Weg <strong>von Grund auf<\/strong> \u2014 auch wenn du WordPress nur als Leser kennst oder noch nie von \u201eREST API\u201c oder \u201eFrontmatter\u201c geh&#246;rt hast.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Kurzfassung<\/h2>\n\r\n\n<ol class=\"wp-block-list\">\r\n\n<li><strong>Schreiben<\/strong> passiert in einer Datei (<code>.md<\/code>), nicht zwingend im WordPress-Editor.<\/li>\n\r\n\n<li>Ein <strong>PowerShell-Skript<\/strong> &#252;bersetzt den Text in das Format, das WordPress intern f&#252;r den Block-Editor braucht, und legt einen <strong>Entwurf<\/strong> an oder aktualisiert ihn.<\/li>\n\r\n\n<li><strong>Ver&#246;ffentlichen<\/strong>, Titelbild und letzte Korrekturen mache ich <strong>bewusst selbst<\/strong> im WordPress-Backend \u2014 nichts geht ohne meinen Klick live.<\/li>\n\r\n<\/ol>\n\r\n\n<p class=\"wp-block-paragraph\">Der Rest des Textes geht in die Tiefe: Begriffe, Motivation, Ablauf, Grenzen und (am Ende) die technische Karte f&#252;r Entwickler.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Was WordPress hier &#252;berhaupt ist<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>WordPress<\/strong> ist die Software hinter <a href=\"https:\/\/www.fabricioruch.ch\">fabricioruch.ch<\/a>: Sie speichert Beitr&#228;ge, Kategorien, Tags, Bilder und liefert die Seiten aus. Man spricht oft von einem <strong>CMS<\/strong> (Content-Management-System) \u2014 einer Verwaltungsoberfl&#228;che f&#252;r Inhalte, ohne dass jeder Artikel handcodiertes HTML sein muss.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">F&#252;r Autoren gibt es das <strong>Backend<\/strong> (wp-admin): Login, Beitragsliste, Editor. F&#252;r Besucher gibt es das <strong>Theme<\/strong> \u2014 das Aussehen (Typografie, Abst&#228;nde, Code-Bl&#246;cke, Kategorie-Navigation). Mein Theme liegt im gleichen Git-Repository wie die Skripte; der Blog bleibt also \u201eWordPress\u201c, nicht eine komplett separate Website.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Wie ein Artikel \u201enormalerweise\u201c entsteht<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">Der <strong>Block-Editor<\/strong> (seit WordPress 5 auch <strong>Gutenberg<\/strong> genannt) zeigt den Text als <strong>Bl&#246;cke<\/strong>: Absatz, &#220;berschrift, Liste, Code, Bild, Tabelle, \u2026 Jeder Block hat Einstellungen in der Seitenleiste. Das ist flexibel und f&#252;r viele Autoren genau richtig.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">Typischer Ablauf:<\/p>\n\r\n\n<ol class=\"wp-block-list\">\r\n\n<li>Im Backend \u201eBeitrag erstellen\u201c.<\/li>\n\r\n\n<li>Titel und Bl&#246;cke im Editor bauen.<\/li>\n\r\n\n<li>Kategorie und Schlagw&#246;rter w&#228;hlen.<\/li>\n\r\n\n<li>Vorschau ansehen.<\/li>\n\r\n\n<li>Ver&#246;ffentlichen oder als Entwurf speichern.<\/li>\n\r\n<\/ol>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Entwurf<\/strong> (<code>draft<\/code>) bedeutet: Der Beitrag ist gespeichert, aber f&#252;r normale Besucher noch nicht sichtbar (nur mit spezieller Vorschau oder als eingeloggter Autor). Genau diesen Status setzt mein Import \u2014 bewusst, damit nichts versehentlich live geht.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Was ich anders mache \u2014 und warum<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">Ich schreibe viele technische Texte <strong>wie Quellcode<\/strong>: in <strong>Git<\/strong> versioniert, mit klaren Zeilen&#228;nderungen (<code>git diff<\/code>), oft zusammen mit Theme- oder Skript-&#196;nderungen. Daf&#252;r eignet sich <strong>Markdown<\/strong> besser als Klicken im Editor.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Markdown<\/strong> ist eine einfache Schreibweise f&#252;r strukturierten Text: <code>##<\/code> f&#252;r Zwischen&#252;berschriften, <code>**fett**<\/code>, Listen mit <code>-<\/code>, Code in Zeilen mit drei Backticks, Tabellen mit <code>|<\/code>. Die Datei bleibt <strong>lesbar als Plain Text<\/strong> \u2014 in VS Code, Cursor oder jedem Editor.<\/p>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Was ich brauche<\/th>\r\n<th>Block-Editor allein<\/th>\r\n<th>Markdown-Datei + Import<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td>&#196;nderungen nachvollziehen<\/td>\r\n<td>WordPress-Revisionen; schwer mit Code zu vergleichen<\/td>\r\n<td>Git zeigt jede Zeile<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Text von KI \/ Skript erzeugen<\/td>\r\n<td>Copy-Paste, Format geht kaputt<\/td>\r\n<td>Agent schreibt eine Datei<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Gleichen Artikel erneut hochladen<\/td>\r\n<td>Manuell im Editor nachziehen<\/td>\r\n<td>Gleicher Dateiname\/Slug \u2192 Update<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Lesen wie auf der Website<\/td>\r\n<td>Vorschau im Backend<\/td>\r\n<td>Entwurf im echten Theme nach Import<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Kategorien &amp; Tags<\/td>\r\n<td>Per Klick<\/td>\r\n<td>In der Datei als Metadaten<\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Das ist <strong>nicht<\/strong> \u201eWordPress abschaffen\u201c. Besucher merken nichts. Es ist nur ein <strong>anderer Eingang<\/strong> f&#252;r die Artikel, die ich schon im Repository denke.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Content-as-Code<\/strong> hei&#223;t hier schlicht: Der Entwurf ist eine Datei im Projekt \u2014 &#228;hnlich wie Konfiguration oder Tests \u2014 nicht nur ein Eintrag in der Datenbank. Live-Schalten bleibt eine bewusste menschliche Entscheidung im Backend.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Begriffe, die im Text vorkommen<\/h2>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Begriff<\/th>\r\n<th>Kurz erkl&#228;rt<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td><strong>Slug<\/strong><\/td>\r\n<td>Der URL-Teil des Beitrags, z.\u202fB. <code>markdown-entwuerfe-wordpress-ohne-block-editor<\/code>. Sollte stabil bleiben, wenn du denselben Artikel aktualisierst.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Frontmatter<\/strong><\/td>\r\n<td>Metadaten <strong>oben in der Datei<\/strong> zwischen <code>---<\/code> Zeilen: Titel, Slug, Kategorien, Tags. Kein Markdown, sondern YAML (eine listenfreundliche Konfigurationssyntax).<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Kategorie<\/strong><\/td>\r\n<td>Grobe Einordnung im Blog (hierarchisch, z.\u202fB. System Engineering \u2192 Automation). Im Theme z&#228;hlt die <strong>erste<\/strong> Kategorie in der Liste als \u201eHaupt\u201c-Kategorie.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Tag<\/strong><\/td>\r\n<td>Feineres Schlagwort (z.\u202fB. <code>wordpress<\/code>, <code>field-note<\/code>). Keine <code>&gt;<\/code>-Pfade wie bei Kategorien.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Taxonomie<\/strong><\/td>\r\n<td>Sammelwort f&#252;r Kategorien und Tags \u2014 die \u201eSchubladen\u201c des Blogs.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>REST API<\/strong><\/td>\r\n<td>Eine HTTP-Schnittstelle, mit der Programme Beitr&#228;ge lesen\/schreiben k&#246;nnen \u2014 statt nur der Maus im Browser.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Application Password<\/strong><\/td>\r\n<td>Ein von WordPress erzeugtes <strong>App-Passwort<\/strong> (nicht dein Login-Passwort), nur f&#252;r Skripte. Liegt lokal in einer Datei, die <strong>nicht<\/strong> ins Git kommt.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Gutenberg \/ Bl&#246;cke<\/strong><\/td>\r\n<td>WordPress speichert Inhalt intern als Bl&#246;cke mit speziellen HTML-Kommentaren. Der Import muss dieses Format treffen, sonst warnt der Editor.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Dry-Run<\/strong><\/td>\r\n<td>Skript l&#228;uft durch, <strong>schreibt aber nichts<\/strong> \u2014 du siehst nur, was passieren <em>w&#252;rde<\/em>.<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Preflight<\/strong><\/td>\r\n<td>Automatische Checks im Repository (Tests, Theme-Regeln), bevor etwas deployt wird.<\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Wenn du nur <strong>lesen<\/strong> willst, reichen Einleitung, Begriffe, Ablauf und \u201eWas bleibt manuell\u201c \u2014 der Abschnitt <strong>Technische Vertiefung<\/strong> ist f&#252;r Menschen, die selbst am Repository arbeiten.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Von der Datei zum WordPress-Entwurf (Schritt f&#252;r Schritt)<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">Stell dir drei Stationen vor:<\/p>\n\r\n\n<pre class=\"wp-block-code\"><code>  [1] Textdatei auf dem PC          [2] Skript auf dem PC           [3] WordPress (Server)\r\n      content\/drafts\/mein-post.md  \u2192  import-post-draft.ps1      \u2192   Beitrag als Entwurf\r\n      Titel, Kategorien, Markdown     &#252;bersetzen &amp; pr&#252;fen            im Backend sichtbar<\/code><\/pre>\n\r\n\n<h3 class=\"wp-block-heading\">Station 1: Die Datei anlegen<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\">Die Arbeitskopie liegt unter <code>content\/drafts\/<\/code> (bewusst <strong>nicht<\/strong> im &#246;ffentlichen Git \u2014 Entw&#252;rfe sind privat auf der Festplatte). Oben steht das Frontmatter, darunter der Artikeltext in Markdown.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">Ein <strong>minimales<\/strong> Beispiel (nur zur Illustration):<\/p>\n\r\n\n<pre class=\"wp-block-code\"><code>---\r\ntitle: &quot;Kurznotiz: REST-Route&quot;\r\nslug: kurznotiz-rest-route\r\ncomments: closed\r\ncategories:\r\n  - &quot;System Engineering &gt; Automation&quot;\r\ntags:\r\n  - field-note\r\n  - german\r\n---\r\n\r\n## Ein Abschnitt\r\n\r\nEin Absatz Text. Keine &#220;berschrift mit einer einzelnen `#` Zeile \u2014 der **Titel** oben im Frontmatter ist die einzige H1; das Theme zeigt sie auf der Seite.<\/code><\/pre>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Kommentare<\/strong> sind bei mir standardm&#228;&#223;ig <strong>geschlossen<\/strong> (<code>comments: closed<\/code>), au&#223;er ich schreibe explizit <code>open<\/code>.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Station 2: Skript ausf&#252;hren (erst ohne Schreiben)<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\">Im Projektordner (PowerShell):<\/p>\n\r\n\n<pre class=\"wp-block-code\"><code>pwsh .\/scripts\/content\/cmd\/import-post-draft.ps1 -Path content\/drafts\/mein-post.md<\/code><\/pre>\n\r\n\n<p class=\"wp-block-paragraph\">Ohne Zusatzflag ist das ein <strong>Dry-Run<\/strong>: Du siehst u.\u202fa. welche Kategorie-IDs gesetzt w&#252;rden, wie lang der Inhalt ist, ob ein <strong>neuer<\/strong> Entwurf oder ein <strong>Update<\/strong> ansteht. Nichts wird an WordPress ge&#228;ndert.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">Wenn die Ausgabe passt, kommt der echte Upload (Produktion nur mit extra Best&#228;tigung):<\/p>\n\r\n\n<pre class=\"wp-block-code\"><code>pwsh .\/scripts\/content\/cmd\/import-post-draft.ps1 `\r\n  -Path content\/drafts\/mein-post.md `\r\n  -Apply -AllowProduction<\/code><\/pre>\n\r\n\n<p class=\"wp-block-paragraph\"><code>-AllowProduction<\/code> ist eine <strong>Sicherheitsleine<\/strong>: Das Skript verweigert sonst Schreibzugriffe auf die Live-Website \u2014 damit ein Tippfehler im Terminal nicht sofort den echten Blog &#252;berschreibt.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Lokal testen<\/strong> (WordPress in Docker auf dem Rechner) geht mit anderer URL und anderer Credential-Datei \u2014 siehe <code>docs\/development\/local-development.md<\/code>.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Station 3: Im Backend fertig machen<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\">Nach erfolgreichem Import:<\/p>\n\r\n\n<ol class=\"wp-block-list\">\r\n\n<li>Im WordPress-Backend den <strong>Entwurf<\/strong> &#246;ffnen.<\/li>\n\r\n\n<li>Pr&#252;fen, ob der Block-Editor <strong>keine<\/strong> Meldung \u201eung&#252;ltiger Block\u201c zeigt.<\/li>\n\r\n\n<li><strong>Beitragsbild<\/strong> (Featured Image) setzen \u2014 das macht das Skript (noch) nicht.<\/li>\n\r\n\n<li><strong>Vorschau<\/strong> im echten Theme: Code, Tabellen, Fu&#223;noten.<\/li>\n\r\n\n<li><strong>Ver&#246;ffentlichen<\/strong> \u2014 oder als Entwurf lassen.<\/li>\n\r\n<\/ol>\n\r\n\n<p class=\"wp-block-paragraph\">So bleibt die <strong>redaktionelle Kontrolle<\/strong> bei mir; das Skript ist Transport und Formatierung, nicht der rote Knopf \u201elive\u201c.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Was das Skript intern tut (ohne Code lesen zu m&#252;ssen)<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">In groben Worten:<\/p>\n\r\n\n<ol class=\"wp-block-list\">\r\n\n<li><strong>Datei lesen<\/strong> und Frontmatter von Body trennen.<\/li>\n\r\n\n<li><strong>Pr&#252;fen<\/strong> (z.\u202fB. Pflichtfelder, kaputte Fu&#223;noten, gef&#228;hrliche Link-Arten).<\/li>\n\r\n\n<li><strong>Markdown in Block-Markup umwandeln<\/strong> \u2014 nicht nur \u201eHTML\u201c, sondern das spezielle Gutenberg-Format mit Kommentaren wie <code>&lt;!-- wp:paragraph --&gt;<\/code>.<\/li>\n\r\n\n<li><strong>Kategorien und Tags aufl&#246;sen<\/strong> (existieren sie? sonst optional anlegen \u2014 mit denselben Regeln wie andere Taxonomie-Skripte im Repo).<\/li>\n\r\n\n<li><strong>Per REST API<\/strong> den Beitrag als Entwurf anlegen oder aktualisieren.<\/li>\n\r\n\n<li><strong>Merken<\/strong>, welche WordPress-Post-ID zu welchem Slug geh&#246;rt (lokale Datei <code>.import-log.json<\/code>, gitignored), damit ein erneuter Import denselben Beitrag aktualisiert statt einen Duplikat anzulegen.<\/li>\n\r\n<\/ol>\n\r\n\n<p class=\"wp-block-paragraph\">Wenn ein Beitrag <strong>schon ver&#246;ffentlicht<\/strong> war, wird er beim Update <strong>nicht<\/strong> automatisch wieder auf \u201eEntwurf\u201c zur&#252;ckgestellt \u2014 das Skript &#228;ndert den Status dann nicht.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Was bewusst <em>nicht<\/em> automatisiert ist<\/h2>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Thema<\/th>\r\n<th>Warum manuell<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td><strong>Ver&#246;ffentlichen<\/strong><\/td>\r\n<td>Kein versehentliches Live-Schalten durch Skript oder CI<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Beitragsbild<\/strong><\/td>\r\n<td>Bildauswahl und Rechte sind redaktionell<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Letzte Feinheiten im Editor<\/strong><\/td>\r\n<td>Manchmal ein Wort, ein Block-Abstand \u2014 schneller im Auge als in Regeln<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Vollst&#228;ndiges \u201ejedes Markdown der Welt\u201c<\/strong><\/td>\r\n<td>Nur die Formate, die der Konverter und das Theme sauber darstellen<\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Plugins vom Typ \u201eMarkdown einf&#252;gen und fertig\u201c habe ich <strong>nicht<\/strong> als Kernl&#246;sung gew&#228;hlt: Ich will Regeln, Tests und Agent-Briefings <strong>im gleichen Repository<\/strong> wie Theme und Skripte \u2014 nicht eine Blackbox im WordPress-Plugin-Verzeichnis.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Warum der Block-Editor trotzdem wichtig bleibt<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">WordPress <strong>erwartet<\/strong> f&#252;r viele Inhalte <strong>Bl&#246;cke<\/strong>, nicht beliebiges HTML in einem Rutsch. Wenn der Import nur <code>&lt;p&gt;Hello&lt;\/p&gt;<\/code> schreibt, ohne die Block-Kommentare, kann der Editor warnen oder alles in einen \u201eklassischen\u201c Block packen \u2014 unhandlich f&#252;r sp&#228;tere Bearbeitung.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">Deshalb baut die Pipeline <strong>editor-taugliche<\/strong> Bl&#246;cke: Abs&#228;tze, &#220;berschriften, Listen, Code, Tabellen, Bilder, Trennlinien, Zitate. Das kostet Wartung (WordPress-Updates, Serialisierung), aber der Entwurf <strong>sieht im Backend aus wie ein normal geschriebener Post<\/strong>.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Praxis-Tipp f&#252;r Neugierige:<\/strong> Code-Bl&#246;cke werden absichtlich <strong>schlicht<\/strong> importiert (ohne extra Sprach-Attribut im Block), weil mein Editor sonst \u201eung&#252;ltiger Inhalt\u201c meldete; die <strong>Syntax-Farben auf der Website<\/strong> kommen vom Theme (<code>code-highlighting.js<\/code>), nicht zwingend vom Editor.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Workflow mit KI (Cursor o.\u202f&#196;.) \u2014 in Alltagssprache<\/h2>\n\r\n\n<ol class=\"wp-block-list\">\r\n\n<li>Ich gebe Kontext aus einer Briefing-Datei im Repo (Sprache, Art des Posts, Kategorie-Vorschl&#228;ge).<\/li>\n\r\n\n<li>Der Assistent erzeugt oder erweitert eine <code>.md<\/code>-Datei unter <code>content\/drafts\/<\/code>.<\/li>\n\r\n\n<li>Ich lese die &#196;nderung wie bei Code (<strong>Diff<\/strong>), korrigiere Frontmatter (z.\u202fB. erste Kategorie = Hauptkategorie).<\/li>\n\r\n\n<li>Dry-Run, dann Apply.<\/li>\n\r\n\n<li>Im Backend: Bild, Vorschau, Publish.<\/li>\n\r\n<\/ol>\n\r\n\n<p class=\"wp-block-paragraph\">Die KI <strong>ersetzt<\/strong> nicht die Verantwortung f&#252;rs Ver&#246;ffentlichen; sie <strong>beschleunigt<\/strong> das erste und zweite Entwerfen in einem Format, das das Skript versteht.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Typische Probleme (auch ohne Entwickler-Jargon)<\/h2>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Was du siehst<\/th>\r\n<th>Was es meist bedeutet<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td>Skript bricht mit \u201eFootnote\u201c ab<\/td>\r\n<td>Im Text steht eine Fu&#223;note ohne Erkl&#228;rung am Ende der Datei<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>\u201eRefusing \u2026 production\u201c<\/td>\r\n<td><code>-AllowProduction<\/code> fehlt beim echten Upload<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>\u201eSlug already exists\u201c<\/td>\r\n<td>Es gibt schon einen Beitrag mit dieser URL; Import-Log oder <code>-AdoptExistingSlug<\/code><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Gelber Banner im Editor \u201eung&#252;ltiger Block\u201c<\/td>\r\n<td>Format passt nicht zu WordPress \u2014 Pipeline anpassen oder Post im Editor bereinigen<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Login schl&#228;gt fehl<\/td>\r\n<td>Application Password oder Benutzername in <code>.env\/wp<\/code> pr&#252;fen (Login-Name, nicht Anzeigename)<\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Nach dem Anlegen <strong>neuer<\/strong> Kategorien oder Tags im Import lohnt sich im Repo noch ein Taxonomie-Audit \u2014 damit die Schubladen langfristig sauber bleiben.<\/p>\n\r\n\n<h2 class=\"wp-block-heading\">Checkliste vor dem Ver&#246;ffentlichen<\/h2>\n\r\n\n<ul class=\"wp-block-list contains-task-list\">\r\n\n<li>Titel, Slug, Kategorien und Tags im Frontmatter stimmen (erste Kategorie = Hauptkategorie).<\/li>\n\r\n\n<li>Dry-Run ohne Fehler.<\/li>\n\r\n\n<li><code>-Apply<\/code> ausgef&#252;hrt, Erfolgsmeldung mit Post-ID.<\/li>\n\r\n\n<li>Entwurf im Backend: keine Block-Fehler.<\/li>\n\r\n\n<li>Beitragsbild gesetzt.<\/li>\n\r\n\n<li>Vorschau auf der Website (Handy\/Desktop, Code, Tabellen).<\/li>\n\r\n\n<li>Ver&#246;ffentlichen \u2014 oder Entwurf l&#246;schen, wenn es nur ein Test war.<\/li>\n\r\n<\/ul>\n\r\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\r\n\n<h2 class=\"wp-block-heading\">Technische Vertiefung (Repository &amp; Module)<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">Der folgende Teil richtet sich an Leser, die im Projekt <strong>fabricio-technical-journal<\/strong> mitarbeiten oder einen &#228;hnlichen Aufbau planen.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Architektur<\/h3>\n\r\n\n<pre class=\"wp-block-code\"><code>  content\/drafts\/post.md          scripts\/content\/\r\n  (YAML + Markdown)                    \u2502\r\n        \u2502                              \u251c\u2500 Parse (YamlDotNet)\r\n        \u2502                              \u251c\u2500 Validate (Regeln, Fu&#223;noten, URLs)\r\n        \u25bc                              \u251c\u2500 Convert \u2192 &lt;!-- wp:* --&gt; \u2026\r\n  import-post-draft.ps1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u251c\u2500 Resolve Taxonomie (wp-taxonomy-apply)\r\n        \u2502                              \u251c\u2500 Build REST payload\r\n        \u2502                              \u2514\u2500 Invoke-ImportPostDraft\r\n        \u25bc\r\n  .env\/wp (Application Password)\r\n        \u2502\r\n        \u25bc\r\n  REST: index.php?rest_route=\/wp\/v2\/posts\r\n        \u2502\r\n        \u25bc\r\n  Post status: draft  \u2192  manuell: Preview, Bild, Publish<\/code><\/pre>\n\r\n\n<p class=\"wp-block-paragraph\">Ein gemeinsamer REST-Client (<code>scripts\/taxonomy\/lib\/wp-rest.ps1<\/code>) dient Taxonomie-Skripten und Content-Import. Auf dieser Installation ist <code>index.php?rest_route=\u2026<\/code> der zuverl&#228;ssige Einstieg (nicht immer <code>\/wp-json\/<\/code>).<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Ziele und Grenzen (v1)<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Kann:<\/strong><\/p>\n\r\n\n<ul class=\"wp-block-list\">\r\n\n<li>Markdown oder <code>format: html<\/code> (mit Sanitizer) importieren.<\/li>\n\r\n\n<li>Kategorien als Pfad <code>Root &gt; \u2026 &gt; Leaf<\/code>; Tags als Slugs; erste Kategorie = primary im Theme.<\/li>\n\r\n\n<li>Kommentare default <code>closed<\/code>.<\/li>\n\r\n\n<li>Re-Import per Slug \u2192 Post-ID in <code>content\/drafts\/.import-log.json<\/code>.<\/li>\n\r\n\n<li>Markdown: &#220;berschriften <code>##<\/code>\u2013<code>####<\/code>, Fett\/Kursiv, Links, Bilder, Listen, Tasks, Tabellen, Zitate, Trennlinie, Code-Fences, Fu&#223;noten<sup class=\"footnote-ref\"><a href=\"#fn-fn-tech\" id=\"fnref-fn-tech\">1<\/a><\/sup>.<\/li>\n\r\n<\/ul>\n\r\n\n<p class=\"wp-block-paragraph\"><strong>Kann nicht (bewusst):<\/strong><\/p>\n\r\n\n<ul class=\"wp-block-list\">\r\n\n<li>Auto-Publish oder Scheduling.<\/li>\n\r\n\n<li>Featured Image per REST.<\/li>\n\r\n\n<li>Jedes GFM-Feature der Welt.<\/li>\n\r\n\n<li>Taxonomie-Politik ersetzen \u2014 nach neuen Terms Audits fahren.<\/li>\n\r\n<\/ul>\n\r\n\n<h3 class=\"wp-block-heading\">Frontmatter (Referenz)<\/h3>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Feld<\/th>\r\n<th>Pflicht<\/th>\r\n<th>Hinweis<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td><code>title<\/code><\/td>\r\n<td>ja<\/td>\r\n<td>Kein einzelnes <code>#<\/code> im Body<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>slug<\/code><\/td>\r\n<td>empfohlen<\/td>\r\n<td>Bei Umlauten explizit (<code>entwuerfe<\/code>)<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>categories<\/code><\/td>\r\n<td>ja<\/td>\r\n<td>Erste Zeile = primary<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>tags<\/code><\/td>\r\n<td>ja<\/td>\r\n<td><code>lowercase-mit-bindestrich<\/code><\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>comments<\/code><\/td>\r\n<td>nein<\/td>\r\n<td>Default <code>closed<\/code><\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>excerpt<\/code><\/td>\r\n<td>nein<\/td>\r\n<td>Mehrzeilig mit `excerpt: \\<\/td>\r\n<td>` m&#246;glich<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>format<\/code><\/td>\r\n<td>nein<\/td>\r\n<td><code>markdown<\/code> oder <code>html<\/code><\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Kategorien: nur <strong>Blatt<\/strong> der Hierarchie zuweisen, nicht jeden Vorfahren doppelt. Tags: keine <code>&gt;<\/code>-Pfade.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Module unter <code>scripts\/content\/<\/code><\/h3>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Modul<\/th>\r\n<th>Aufgabe<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td><code>cmd\/import-post-draft.ps1<\/code><\/td>\r\n<td>CLI<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Invoke-ImportPostDraft.ps1<\/code><\/td>\r\n<td>Orchestrierung<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Parse-DraftMarkdown.ps1<\/code><\/td>\r\n<td>Frontmatter \/ Body<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Validate-DraftFrontmatter.ps1<\/code><\/td>\r\n<td>Regeln, URLs<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Convert-*.ps1<\/code><\/td>\r\n<td>Markdown \u2192 Bl&#246;cke<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Gutenberg-Blocks.ps1<\/code><\/td>\r\n<td>Block-Helfer<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Build-WpPostPayload.ps1<\/code><\/td>\r\n<td><code>draft<\/code> nur bei neuem Post<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Import-DraftState.ps1<\/code><\/td>\r\n<td>Import-Log<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>lib\/Resolve-DraftTaxonomy.ps1<\/code><\/td>\r\n<td>Kategorien\/Tags<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><code>test\/run-all.ps1<\/code><\/td>\r\n<td>Tests; Teil von Theme-Preflight<\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Einmal pro Clone: <code>pwsh .\/scripts\/content\/cmd\/restore-content-deps.ps1<\/code> (YamlDotNet).<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Gutenberg-Details<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\">Serialisierung muss zu Core-Bl&#246;cken passen: <code>wp:paragraph<\/code>, <code>wp:code<\/code> ohne st&#246;rendes <code>language<\/code>-Attribut im Kommentar, <code>wp:list<\/code> \/ Tasks mit <code>contains-task-list<\/code>, Tabellen als <code>wp:table<\/code>, Fu&#223;noten-Abschnitt oft als <code>wp:html<\/code> plus Theme-CSS (<code>reading.css<\/code>). Golden-Tests: <code>Gutenberg-Serialization.Tests.ps1<\/code>.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Sicherheit<\/h3>\n\r\n\n<p class=\"wp-block-paragraph\">Application Password in <code>.env\/wp<\/code>, nie committen. <code>-AllowProduction<\/code> f&#252;r Prod-<code>-Apply<\/code>. Validierung blockiert <code>javascript:<\/code> \/ <code>data:<\/code> in Links. Live-Debug-Skripte nur mit <code>CONTENT_IMPORT_REQUIRE_LIVE_REST=1<\/code>.<\/p>\n\r\n\n<h3 class=\"wp-block-heading\">Sonderf&#228;lle<\/h3>\n\r\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr>\r\n<th>Situation<\/th>\r\n<th>Aktion<\/th>\r\n<\/tr><\/thead>\r\n<tbody>\r\n<tr>\r\n<td>Slug in WP, nicht im Log<\/td>\r\n<td><code>-AdoptExistingSlug<\/code> oder Log-Eintrag<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Payload ohne Schreiben<\/td>\r\n<td><code>-Apply -WhatIf<\/code><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Text ge&#228;ndert, gleicher Slug<\/td>\r\n<td>Erneut <code>-Apply<\/code><\/td>\r\n<\/tr>\r\n<\/tbody><\/table><\/figure>\n\r\n\n<p class=\"wp-block-paragraph\">Breiter Block-Smoke-Test: <code>scripts\/content\/examples\/content-entwuerfe-markdown-import-smoke-test.md<\/code>.<\/p>\n\r\n\n<pre class=\"wp-block-code\"><code>pwsh .\/scripts\/content\/test\/run-all.ps1\r\npwsh .\/scripts\/theme\/preflight.ps1 -Strict<\/code><\/pre>\n\r\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\r\n\n<p class=\"wp-block-paragraph\">Zwei Wege, ein Blog: <strong>Im Editor schreiben<\/strong> bleibt der Default. <strong>Markdown plus Import<\/strong> ist mein Werkzeug f&#252;r technische Texte, die ich versionieren, automatisieren oder mit KI vorbereiten will \u2014 ohne WordPress als Leser-Erlebnis abzuschaffen. Wer nur mitlesen will, merkt h&#246;chstens, dass Field Notes oft sehr strukturiert wirken; wer selbst baut, kann im Repository nachziehen, was hier in Worte gefasst ist.<\/p>\n\r\n\n<p class=\"wp-block-paragraph\">Geplante Erweiterungen (noch offen): Beitragsbild per REST, optional CI nur f&#252;r Content-Tests \u2014 getrennt vom Theme-Deploy.<\/p>\n\r\n\n<section class=\"footnotes\">\r\n<ol>\r\n<li id=\"fn-fn-tech\">Vertrag und Beispiele: <code>docs\/development\/content-draft-format.md<\/code>, <code>scripts\/content\/README.md<\/code>, KI: <code>docs\/development\/ai-post-briefing.md<\/code>. <a href=\"#fnref-fn-tech\" class=\"footnote-backref\">\u21a9<\/a><\/li>\r\n<\/ol><\/section>\n","protected":false},"excerpt":{"rendered":"<p>F\u00fcr Leser ohne Vorwissen: Wie dieser Blog technische Texte schreibt und in WordPress<br \/>\nlandet \u2014 warum nicht im Block-Editor, was Markdown und ein Import-Skript bedeuten,<br \/>\nwas automatisch passiert, was bewusst manuell bleibt, und wo die technischen Details stehen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[60,64],"tags":[70,87,241,239,185,212],"class_list":["post-413","post","type-post","status-publish","format-standard","hentry","category-automation","category-continuous-integration-ci-continuous-delivery-cd","tag-field-note","tag-german","tag-git","tag-markdown","tag-powershell","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/413","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=413"}],"version-history":[{"count":3,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/413\/revisions"}],"predecessor-version":[{"id":416,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/413\/revisions\/416"}],"wp:attachment":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}