385 lines
10 KiB
Markdown
385 lines
10 KiB
Markdown
# 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**
|
|
```bash
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
Sie sollten jetzt `(.venv)` am Anfang Ihrer Kommandozeile sehen.
|
|
|
|
3. **Python-Abhängigkeiten installieren**
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
4. **Umgebungsvariablen konfigurieren**
|
|
|
|
Kopieren Sie `.env.example` zu `.env` und tragen Sie Ihre Credentials ein:
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Bearbeiten Sie `.env`:
|
|
```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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```yaml
|
|
# 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:
|
|
|
|
```bash
|
|
source .venv/bin/activate
|
|
python workflow.py posts.yaml
|
|
```
|
|
|
|
### Modus 3: Ganzes Forgejo/Gitea-Repository
|
|
|
|
Verarbeiten Sie alle Markdown-Dateien aus einem Repository:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```markdown
|
|
---
|
|
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:
|
|
|
|
```yaml
|
|
---
|
|
'@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`)
|
|
|
|
```python
|
|
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:
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```bash
|
|
python workflow.py "https://example.com/artikel.md"
|
|
```
|
|
|
|
### Beispiel 2: Lokale Datei
|
|
|
|
```bash
|
|
python workflow.py "content/beispiel-beitrag.md"
|
|
```
|
|
|
|
### Beispiel 3: Mehrere URLs aus YAML
|
|
|
|
```yaml
|
|
posts:
|
|
- url: "https://example.com/artikel1.md"
|
|
- url: "https://example.com/artikel2.md"
|
|
- file: "content/lokaler-artikel.md"
|
|
```
|
|
|
|
```bash
|
|
python workflow.py posts.yaml
|
|
```
|
|
|
|
### Beispiel 4: Forgejo-Repository
|
|
|
|
```bash
|
|
python workflow.py --repo "https://codeberg.org/user/repo" main
|
|
```
|
|
|
|
### Beispiel 5: Metadaten überschreiben
|
|
|
|
```yaml
|
|
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**:
|
|
```bash
|
|
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.
|