MD2WordPress/README.md
2025-11-05 06:25:26 +01:00

10 KiB

WordPress News Import

Automatisierter Workflow zum Erstellen von WordPress-Beiträgen aus Markdown-Dateien über die WordPress REST-API.

Neu: Metadaten werden automatisch aus dem YAML-Frontmatter der Markdown-Dateien extrahiert!

⚠️ Bekannte Einschränkungen

Autor-Zuordnung:

  • Beiträge werden immer dem importierenden WordPress-Benutzer zugeordnet (WordPress REST-API Limitation)
  • Der author aus dem Frontmatter wird automatisch als Tag im Format Vorname_Nachname hinzugefügt
  • Beispiel: author: Jörg Lohrer → Tag: Jörg_Lohrer
  • Dies ermöglicht die Filterung nach Autoren über die WordPress-Tag-Taxonomie

Forgejo-Repository-Import:

  • Die Batch-Verarbeitung ganzer Repositories wurde noch nicht ausreichend getestet
  • Empfehlung: Beginnen Sie mit einzelnen URLs: python workflow.py "https://url.de/artikel.md"
  • Zu entwickeln: Robustere Forgejo-API-Integration mit besserer Fehlerbehandlung und Progress-Tracking

Empfohlener Workflow: Testen Sie zunächst mit einzelnen Markdown-URLs, bevor Sie größere Batch-Imports durchführen.

Features

  • Automatische Metadaten-Extraktion: name, description, tags, image, author aus YAML-Frontmatter
  • Autor-zu-Tag-Mapping: Autoren werden automatisch als Tags im Format Vorname_Nachname hinzugefügt
  • Drei Verwendungsmodi: Einzelne URL, YAML-Batch, Forgejo-Repository
  • Duplikatsprüfung: Verhindert das doppelte Erstellen von Beiträgen und Medien
  • Markdown zu HTML: Automatische Konvertierung von Markdown-Inhalten
  • Medien-Upload: Hochladen von Beitragsbildern mit Duplikatsprüfung
  • Kategorien & Tags: Automatische Erstellung fehlender Kategorien und Tags
  • Flexible Quellen: Unterstützt Markdown-URLs, lokale Dateien und Forgejo-Repositories
  • Schema.org Support: Versteht commonMetadata-Strukturen

Voraussetzungen

  • Python 3.7 oder höher
  • WordPress-Installation mit aktivierter REST-API
  • WordPress Anwendungspasswort (Application Password)

Installation

  1. Repository klonen oder herunterladen

  2. Virtuelle Umgebung aktivieren

    source .venv/bin/activate
    

    Sie sollten jetzt (.venv) am Anfang Ihrer Kommandozeile sehen.

  3. Python-Abhängigkeiten installieren

    pip install -r requirements.txt
    
  4. Umgebungsvariablen konfigurieren

    Kopieren Sie .env.example zu .env und tragen Sie Ihre Credentials ein:

    cp .env.example .env
    

    Bearbeiten Sie .env:

    WORDPRESS_URL=https://news.rpi-virtuell.de
    WORDPRESS_USERNAME=ihr_benutzername
    WORDPRESS_APP_PASSWORD=UIVI 23H6 oojL 9iZG g3X2 Aon5
    

WordPress Anwendungspasswort erstellen

  1. Melden Sie sich in WordPress an
  2. Gehen Sie zu Benutzer → Profil
  3. Scrollen Sie zu Anwendungspasswörter
  4. Geben Sie einen Namen ein (z.B. "News Import")
  5. Klicken Sie auf Neues Anwendungspasswort hinzufügen
  6. Kopieren Sie das generierte Passwort in Ihre .env-Datei

Verwendung

Modus 1: Einzelne URL (Am einfachsten!)

Verarbeiten Sie eine einzelne Markdown-URL direkt:

source .venv/bin/activate
python workflow.py "https://example.com/artikel.md"

Alle Metadaten (Titel, Tags, Kategorien, Bild) werden aus dem YAML-Frontmatter der Markdown-Datei extrahiert.

Modus 2: Mehrere URLs aus YAML-Datei

Erstellen Sie eine posts.yaml-Datei:

# Einfache URL-Liste - Metadaten kommen aus dem Frontmatter!
posts:
  - url: "https://example.com/artikel1.md"
  - url: "https://example.com/artikel2.md"
  - file: "content/lokaler-artikel.md"
  
  # Optional: Metadaten überschreiben
  - url: "https://example.com/artikel3.md"
    status: "publish"  # Überschreibt Status aus Frontmatter

settings:
  default_status: "draft"
  skip_duplicates: true
  skip_duplicate_media: true

Dann ausführen:

source .venv/bin/activate
python workflow.py posts.yaml

Modus 3: Ganzes Forgejo/Gitea-Repository

Verarbeiten Sie alle Markdown-Dateien aus einem Repository:

source .venv/bin/activate
python workflow.py --repo "https://codeberg.org/user/repo" main

Dies lädt automatisch alle .md-Dateien aus dem Repository und erstellt WordPress-Beiträge.

Markdown-Frontmatter Format

Ihre Markdown-Dateien sollten YAML-Frontmatter enthalten:

---
name: "Artikel-Titel"
description: "Kurze Zusammenfassung für WordPress-Excerpt"
image: "https://example.com/bild.jpg"
tags:
  - WordPress
  - Tutorial
  - Open Source
categories:
  - Tutorials
author:
  - Max Mustermann
---

# Artikel-Inhalt

Hier beginnt der eigentliche Markdown-Inhalt...

Unterstützte Frontmatter-Felder

Das System extrahiert automatisch:

  • Titel: name oder title
  • Excerpt: description oder summary
  • Beitragsbild: image oder cover.image
  • Tags: tags (Liste oder kommagetrennt)
  • Kategorien: categories (Liste oder kommagetrennt)
  • Autor: author (String oder Liste)
  • Status: status oder aus creativeWorkStatus
  • Datum: date oder datePublished

Schema.org Support

Das System versteht auch Schema.org-Metadaten:

---
'@context': https://schema.org/
type: LearningResource
name: "Artikel-Titel"
description: "Beschreibung"
image: "https://example.com/bild.jpg"
creator:
  - givenName: Max
    familyName: Mustermann
    type: Person
tags:
  - Tag1
  - Tag2
---

Siehe content/beispiel-beitrag.md für ein vollständiges Beispiel.

Struktur

newsimport/
├── .env                    # Credentials (nicht in Git!)
├── .env.example            # Beispiel-Konfiguration
├── .gitignore              # Git-Ignorier-Liste
├── requirements.txt        # Python-Abhängigkeiten
├── wordpress_api.py        # WordPress REST-API Client
├── markdown_parser.py      # YAML-Frontmatter Parser
├── workflow.py             # Haupt-Workflow Script
├── posts.yaml              # Beitrags-Konfiguration (optional)
├── README.md               # Diese Datei
├── QUICKSTART.md           # Schnellstart-Anleitung
├── content/                # Lokale Markdown-Dateien (optional)
│   └── beispiel-beitrag.md
└── images/                 # Lokale Bilder (optional)
    └── *.jpg/png

API-Funktionen

WordPress API Client (wordpress_api.py)

from wordpress_api import WordPressAPI

# API initialisieren
wp = WordPressAPI(url, username, app_password)

# Beitrag erstellen (mit Duplikatsprüfung)
post_id = wp.create_post(
    title="Titel",
    content="<p>HTML-Inhalt</p>",
    status="publish",
    check_duplicate=True
)

# Medien hochladen (mit Duplikatsprüfung)
media_id = wp.upload_media(
    file_path="bild.jpg",
    title="Bild-Titel",
    alt_text="Alt-Text",
    check_duplicate=True
)

# Kategorie holen oder erstellen
cat_id = wp.get_or_create_category("News")

# Tag holen oder erstellen
tag_id = wp.get_or_create_tag("WordPress")

# Auf Duplikate prüfen
existing_post_id = wp.check_post_exists("Titel")
existing_media_id = wp.check_media_exists("bild.jpg")

YAML-Konfiguration (posts.yaml)

Vereinfachte Struktur

Metadaten werden automatisch aus dem Frontmatter extrahiert:

posts:
  - url: "https://example.com/artikel.md"  # URL zur Markdown-Datei
  - file: "content/artikel.md"              # Oder lokale Datei
  
  # Optional: Metadaten überschreiben
  - url: "https://example.com/artikel2.md"
    status: "publish"     # Überschreibt Frontmatter
    categories:           # Ergänzt Frontmatter-Kategorien
      - "Extra-Kategorie"

Globale Einstellungen

settings:
  default_status: "draft"           # Fallback wenn nicht im Frontmatter
  default_author: "admin"           # Fallback wenn nicht im Frontmatter
  skip_duplicates: true             # Bestehende Beiträge überspringen
  skip_duplicate_media: true        # Bestehende Medien überspringen
  markdown_extensions:              # Markdown-Erweiterungen
    - extra
    - codehilite
    - toc

Duplikatsprüfung

Beiträge

Das System prüft vor dem Erstellen, ob ein Beitrag mit dem gleichen Titel bereits existiert. Falls ja, wird die bestehende Post-ID zurückgegeben und kein neuer Beitrag erstellt.

Medien

Vor dem Upload wird geprüft, ob eine Datei mit dem gleichen Namen bereits existiert. Falls ja, wird die bestehende Media-ID verwendet.

Beispiele

Beispiel 1: Einzelne URL direkt

python workflow.py "https://example.com/artikel.md"

Beispiel 2: Lokale Datei

python workflow.py "content/beispiel-beitrag.md"

Beispiel 3: Mehrere URLs aus YAML

posts:
  - url: "https://example.com/artikel1.md"
  - url: "https://example.com/artikel2.md"
  - file: "content/lokaler-artikel.md"
python workflow.py posts.yaml

Beispiel 4: Forgejo-Repository

python workflow.py --repo "https://codeberg.org/user/repo" main

Beispiel 5: Metadaten überschreiben

posts:
  - url: "https://example.com/artikel.md"
    status: "publish"  # Überschreibt Status aus Frontmatter
    categories:        # Ergänzt Kategorien aus Frontmatter
      - "Extra-Kategorie"

Fehlerbehebung

Authentifizierungsfehler

Problem: 401 Unauthorized

Lösung:

  • Überprüfen Sie Username und Anwendungspasswort in .env
  • Stellen Sie sicher, dass das Anwendungspasswort korrekt ist (keine zusätzlichen Leerzeichen)
  • Verifizieren Sie, dass die WordPress REST-API aktiviert ist

Keine Verbindung zu WordPress

Problem: Connection refused oder Timeout

Lösung:

  • Überprüfen Sie die WORDPRESS_URL in .env
  • Stellen Sie sicher, dass WordPress erreichbar ist
  • Prüfen Sie Firewall-Einstellungen

Markdown wird nicht konvertiert

Problem: Markdown-Syntax erscheint im Beitrag

Lösung:

  • Überprüfen Sie, ob markdown installiert ist: pip install markdown
  • Prüfen Sie die Markdown-Syntax in der Quelldatei

Import-Fehler bei Modulen

Problem: ModuleNotFoundError: No module named 'requests'

Lösung:

pip install -r requirements.txt

Sicherheit

⚠️ Wichtig:

  • Committen Sie niemals die .env-Datei mit echten Credentials in Git!
  • Die .gitignore ist bereits so konfiguriert, dass .env ignoriert wird
  • Verwenden Sie .env.example als Vorlage für andere Nutzer

Lizenz

Dieses Projekt steht unter der MIT-Lizenz.

Support

Bei Problemen oder Fragen erstellen Sie bitte ein Issue im Repository.


Hinweis: Dieses Tool wurde für https://news.rpi-virtuell.de entwickelt, funktioniert aber mit jeder WordPress-Installation, die die REST-API unterstützt.