Wissen / Dokumentation / Drupal / Export zurück nach mkdocs/Zensical
Drupal-Inhalte nach mkdocs/Zensical exportieren
Der umgekehrte Weg zu Migration nach Drupal: Inhalte aus einer bestehenden Drupal-Instanz über die JSON:API extrahieren und als Markdown-Dateien in ein mkdocs/Zensical-Doku-Repo (wie dieses hier) überführen.
Hinweis: allgemeine Technik, keine Ankündigung
Wie beim Hin-Weg beschreibt diese Seite die technische Machbarkeit anhand einer beliebigen Drupal-Instanz — sie ist keine Ankündigung, dass Inhalte aus einem konkreten Drupal-System in dieses Repository übernommen werden.
Ablauf
Achtung: Nur Text-Inhalte, Struktur bleibt Handarbeit
Die JSON:API liefert flache Knoten ohne mkdocs-nav:-Hierarchie. Welchem <bereich> (künstliche-intelligenz, entwicklung, kreativ, wissen, rechtliches) eine importierte Seite zugeordnet wird und wo sie in der Navigation einsortiert gehört, muss ein Mensch entscheiden — das Skript unten schlägt dafür nur einen Ziel-Dateipfad vor, trägt aber nichts automatisch in mkdocs.yml ein.
Voraussetzungen
Auf der Drupal-Seite muss die JSON:API bereits aktiv sein (siehe Voraussetzungen in der Migrations-Anleitung):
cd /var/www/drupal-projekt
sudo -u www-data vendor/bin/drush en jsonapi basic_auth -y
Ein Lesezugriff reicht für den Export — anders als beim Import (migration_bot) genügt hier ein Konto/Token mit ausschließlich Leseberechtigung, ein Schreibzugriff ist nicht nötig.
pip install requests
Export-Skript
import pathlib
import re
import subprocess
import requests
from requests.auth import HTTPBasicAuth
DRUPAL_JSONAPI_URL = "https://drupal.wissen-ahrensburg.de/jsonapi/node/page"
AUTH = HTTPBasicAuth("export_reader", "READONLY_PASSWORT")
HEADERS = {"Accept": "application/vnd.api+json"}
# Zielverzeichnis: welcher <bereich> passt, entscheidet ein Mensch beim Sichten
ZIEL_BEREICH = pathlib.Path("docs/wissen/dokumentation/importiert")
def slugify(title):
slug = title.strip().lower()
slug = re.sub(r"[^a-z0-9äöüß]+", "-", slug)
return slug.strip("-")
def html_to_markdown(html_body):
result = subprocess.run(
["pandoc", "-f", "html", "-t", "gfm"],
input=html_body, capture_output=True, text=True,
)
return result.stdout
def fetch_all_pages():
pages, url = [], DRUPAL_JSONAPI_URL
while url:
r = requests.get(url, auth=AUTH, headers=HEADERS)
payload = r.json()
pages += payload["data"]
url = payload.get("links", {}).get("next", {}).get("href")
return pages
ZIEL_BEREICH.mkdir(parents=True, exist_ok=True)
for node in fetch_all_pages():
title = node["attributes"]["title"]
html_body = node["attributes"]["body"]["value"] if node["attributes"].get("body") else ""
markdown_body = html_to_markdown(html_body)
ziel_datei = ZIEL_BEREICH / f"{slugify(title)}.md"
ziel_datei.write_text(f"# {title}\n\n{markdown_body}\n", encoding="utf-8")
print(f"✅ {node['attributes']['drupal_internal__nid']} -> {ziel_datei}")
Tipp: nur veröffentlichte Seiten exportieren
Standardmäßig liefert die JSON:API nur Knoten, auf die das genutzte Konto Leserechte hat — ein unprivilegiertes export_reader-Konto sieht damit ohnehin nur status: true-Seiten. Soll gezielt zwischen veröffentlicht/unveröffentlicht gefiltert werden, lässt sich zusätzlich der Query-Parameter ?filter[status]=1 an DRUPAL_JSONAPI_URL anhängen.
Nachbereitung (nicht automatisierbar)
- Bereich zuordnen: Jede Datei aus
docs/wissen/dokumentation/importiert/in den passenden<bereich>-Ordner verschieben (künstliche-intelligenz,entwicklung,kreativ,wissenoderrechtliches— siehe Struktur inCLAUDE.md). - Nav-Eintrag ergänzen: Für jede Seite einen Eintrag unter
nav:inmkdocs.ymlanlegen — sonst gilt sie als verwaist (Checkliste „Neue Seite anlegen" imzensical-docs-Skill). - Interne Links umschreiben: Drupal-interne Links (
/node/123, Pfad-Aliase) zeigen nicht auf die neuen.md-Pfade — vor der Veröffentlichung durch relative Markdown-Links ersetzen ([Text](../ordner/seite.md)). - Zensical-spezifische Syntax nachziehen: Pandoc erzeugt reines GFM — Admonitions (
!!! note), Tabs (=== "Titel") und Mermaid-Diagramme kennt Pandoc nicht und muss von Hand ergänzt werden, wo sinnvoll. - Bilder/Anhänge: Drupal-Medien liegen unter
sites/default/files/und werden von derbody-HTML nur referenziert, nicht mitexportiert — separat kopieren und Pfade im Markdown anpassen. - Prüfen:
.venv/bin/zensical buildundpython3 .gemini/scripts/check_orphaned_files.pylaufen lassen, bei größerem Umfang dendoc-checker-Subagenten.
Verwandte Themen
- Migration nach Drupal: MediaWiki, XWiki, Wiki.js, mkdocs/Zensical — der Hin-Weg
- Drupal installieren: Composer, PostgreSQL und Nginx
- Pandoc — Grundlagen der Formatkonvertierung
- KI strukturiert das Wiki autonom & Selfhosting-Migration — verwandtes Muster für Markdown-Wiki ↔ Selfhosting-System
- Dokumentationsübersicht