Inhaltsimport

Auf dieser Seite

Das Importsystem von EmDash verwendet eine plugfähige Quellenarchitektur. Jede Quelle kann eine bestimmte Plattform erkennen, analysieren und Inhalte daraus abrufen.

Importquellen

Quell-IDPlattformErkennungOAuthVollständiger Import
wxrWordPress-ExportdateiNeinNeinJa
wordpress-comWordPress.comJaJaJa
wordpress-restSelbstgehostetes WordPressJaNeinNur Erkennung

WXR-Datei-Upload

Die vollständigste Importmethode. Laden Sie eine WordPress eXtended RSS (WXR)-Exportdatei direkt in das Admin-Dashboard hoch.

Funktionen:

  • Alle Beitragstypen (einschließlich benutzerdefinierter)
  • Alle Meta-Felder
  • Entwürfe und private Beiträge
  • Vollständige Taxonomie-Hierarchie
  • Medienanhang-Metadaten

So erhalten Sie eine WXR-Datei:

  1. Gehen Sie im WordPress-Adminbereich zu Werkzeuge → Exportieren
  2. Wählen Sie Alle Inhalte oder bestimmte Beitragstypen
  3. Klicken Sie auf Exportdatei herunterladen
  4. Laden Sie die .xml-Datei in EmDash hoch

WordPress.com OAuth

Für Websites, die auf WordPress.com gehostet werden, können Sie sich über OAuth verbinden, um ohne manuelle Dateiexporte zu importieren.

  1. Geben Sie die URL Ihrer WordPress.com-Website ein
  2. Klicken Sie auf Mit WordPress.com verbinden
  3. Autorisieren Sie EmDash im WordPress.com-Popup
  4. Wählen Sie die zu importierenden Inhalte aus

Was enthalten ist:

  • Veröffentlichte und entworfene Inhalte
  • Private Beiträge (mit Autorisierung)
  • Mediendateien über API
  • Benutzerdefinierte Felder, die der REST-API zugänglich sind

WordPress REST API-Erkennung

Wenn Sie eine URL eingeben, prüft EmDash die Website, um WordPress zu erkennen und verfügbare Inhalte anzuzeigen:

Erkannt: WordPress 6.4
├── Beiträge: 127 (veröffentlicht)
├── Seiten: 12 (veröffentlicht)
└── Medien: 89 Dateien

Hinweis: Entwürfe und private Inhalte erfordern eine Authentifizierung
oder einen vollständigen WXR-Export.

Die REST-Erkennung dient der Information. Für vollständige Importe wird das Hochladen einer WXR-Datei oder die Verbindung über OAuth (für WordPress.com) empfohlen.

Importablauf

Alle Quellen folgen demselben Ablauf:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Verbinden  │────▶│ Analysieren │────▶│ Vorbereiten │────▶│  Ausführen  │
│  (Erkennung/│     │  (Schema-   │     │  (Schema    │     │  (Inhalte   │
│   Upload)   │     │   prüfung)  │     │  erstellen) │     │ importieren)│
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘

Schritt 1: Verbinden

Geben Sie eine URL zur Erkennung ein oder laden Sie eine Datei direkt hoch.

URL-Erkennung führt alle registrierten Quellen parallel aus. Die Übereinstimmung mit der höchsten Zuverlässigkeit bestimmt die vorgeschlagene nächste Aktion:

  • WordPress.com-Website → OAuth-Verbindung anbieten
  • Selbstgehostetes WordPress → Exportanweisungen anzeigen
  • Unbekannt → Datei-Upload vorschlagen

Schritt 2: Analysieren

Die Quelle analysiert den Inhalt und prüft die Schema-Kompatibilität:

Beitragstypen:
├── post (127) → posts [Neue Sammlung]
├── page (12)  → pages [Vorhanden, kompatibel]
├── product (45) → products [3 Felder hinzufügen]
└── revision (234) → [Überspringen - interner Typ]

Erforderliche Schema-Änderungen:
├── Sammlung erstellen: posts
├── Felder zu pages hinzufügen: featured_image
└── Sammlung erstellen: products

Jeder Beitragstyp zeigt seinen Status an:

StatusBedeutung
BereitSammlung existiert mit kompatiblen Feldern
Neue SammlungWird automatisch erstellt
Felder hinzufügenSammlung existiert, fehlende Felder werden ergänzt
InkompatibelFeldtyp-Konflikte (manuelle Korrektur erforderlich)

Schritt 3: Schema vorbereiten

Klicken Sie auf Schema erstellen & importieren, um:

  1. Neue Sammlungen über SchemaRegistry zu erstellen
  2. Fehlende Felder mit korrekten Spaltentypen hinzuzufügen
  3. Inhaltstabellen mit Indizes einzurichten

Schritt 4: Import ausführen

Inhalte werden sequenziell importiert:

  • Gutenberg/HTML wird in Portable Text konvertiert
  • WordPress-Status wird auf EmDash-Status abgebildet
  • WordPress-Autoren werden auf Eigentümerschaft (authorId) und Anzeige-Bylines abgebildet
  • Taxonomien werden erstellt und verknüpft
  • Wiederverwendbare Blöcke (wp_block) werden als Sektionen importiert
  • Fortschritt wird in Echtzeit angezeigt

Verhalten beim Autorenimport:

  • Wenn eine Autorenzuordnung auf einen EmDash-Benutzer verweist, wird die Eigentümerschaft auf diesen Benutzer gesetzt und eine verknüpfte Byline für denselben Benutzer erstellt bzw. wiederverwendet.
  • Wenn keine Benutzerzuordnung vorhanden ist, wird eine Gast-Byline aus der WordPress-Autorenidentität erstellt bzw. wiederverwendet.
  • Importierte Einträge erhalten geordnete Byline-Angaben, wobei die erste Angabe als primaryBylineId gesetzt wird.

Schritt 5: Medienimport (Optional)

Nach dem Inhaltsimport können Sie optional Medien importieren:

  1. Analyse — Zeigt die Anzahl der Anhänge nach Typ

    Gefundene Medien:
    ├── Bilder: 75 Dateien
    ├── Video: 10 Dateien
    └── Sonstige: 4 Dateien
  2. Download — Streamt von WordPress-URLs mit Fortschrittsanzeige

    Medien werden importiert...
    ├── 45 von 89 (50%)
    ├── Aktuell: vacation-photo.jpg
    └── Status: Wird hochgeladen
  3. URLs umschreiben — Inhalte werden automatisch mit neuen URLs aktualisiert

Der Medienimport verwendet Content-Hashing (xxHash64) zur Deduplizierung. Dasselbe Bild, das in mehreren Beiträgen verwendet wird, wird nur einmal gespeichert.

Quellen-Schnittstelle

Importquellen implementieren eine standardisierte Schnittstelle:

interface ImportSource {
	/** Unique identifier */
	id: string;

	/** Display name */
	name: string;

	/** Probe a URL (optional) */
	probe?(url: string): Promise<SourceProbeResult | null>;

	/** Analyze content from this source */
	analyze(input: SourceInput, context: ImportContext): Promise<ImportAnalysis>;

	/** Stream content items */
	fetchContent(input: SourceInput, options: FetchOptions): AsyncGenerator<NormalizedItem>;
}

Eingabetypen

Quellen akzeptieren verschiedene Eingabetypen:

// File upload (WXR)
{ type: "file", file: File }

// URL with optional token (REST API)
{ type: "url", url: string, token?: string }

// OAuth connection (WordPress.com)
{ type: "oauth", url: string, accessToken: string }

Normalisierte Ausgabe

Alle Quellen erzeugen dasselbe normalisierte Format:

interface NormalizedItem {
	sourceId: string | number;
	postType: string;
	status: "publish" | "draft" | "pending" | "private" | "future";
	slug: string;
	title: string;
	content: PortableTextBlock[];
	excerpt?: string;
	date: Date;
	author?: string;
	authors?: string[];
	categories?: string[];
	tags?: string[];
	meta?: Record<string, unknown>;
	featuredImage?: string;
}

API-Endpunkte

Das Importsystem stellt folgende Endpunkte bereit:

URL erkennen

POST /_emdash/api/import/probe
Content-Type: application/json

{ "url": "https://example.com" }

Gibt die erkannte Plattform und die vorgeschlagene Aktion zurück.

WXR analysieren

POST /_emdash/api/import/wordpress/analyze
Content-Type: multipart/form-data

file: [WordPress export .xml]

Gibt die Beitragstyp-Analyse mit Schema-Kompatibilität zurück.

Schema vorbereiten

POST /_emdash/api/import/wordpress/prepare
Content-Type: application/json

{
  "postTypes": [
    { "name": "post", "collection": "posts", "enabled": true }
  ]
}

Erstellt Sammlungen und Felder.

Import ausführen

POST /_emdash/api/import/wordpress/execute
Content-Type: multipart/form-data

file: [WordPress export .xml]
config: { "postTypeMappings": { "post": { "collection": "posts" } } }

Importiert Inhalte in die angegebenen Sammlungen.

Medien importieren

POST /_emdash/api/import/wordpress/media
Content-Type: application/json

{
  "attachments": [{ "id": 123, "url": "https://..." }],
  "stream": true
}

Streamt NDJSON-Fortschrittsaktualisierungen während des Herunterladens/Hochladens.

URLs umschreiben

POST /_emdash/api/import/wordpress/rewrite-urls
Content-Type: application/json

{
  "urlMap": { "https://old.com/image.jpg": "/_emdash/media/abc123" }
}

Aktualisiert Portable Text-Inhalte mit neuen Medien-URLs.

Fehlerbehandlung

Behebbare Fehler

  • Netzwerk-Timeout — Wird mit Backoff erneut versucht
  • Einzelnes Element nicht parsbar — Protokolliert, übersprungen, Import wird fortgesetzt
  • Medien-Download fehlgeschlagen — Zur manuellen Bearbeitung markiert

Schwerwiegende Fehler

  • Ungültiges Dateiformat — Import wird mit Fehlermeldung gestoppt
  • Datenbankverbindung verloren — Import wird pausiert, Fortsetzung möglich
  • Speicherkontingent überschritten — Import wird gestoppt, Nutzung wird angezeigt

Fehlerbericht

Nach dem Import:

Import abgeschlossen

✓ 125 Beiträge importiert
✓ 12 Seiten importiert
✓ 85 Medienreferenzen erfasst

⚠ 2 Elemente mit Warnungen:
  - Beitrag "Special Characters ñ" - Titel-Kodierung korrigiert
  - Seite "About" - doppelter Slug umbenannt in "about-1"

✗ 1 Element fehlgeschlagen:
  - Beitrag-ID 456 - Fehler bei der Inhaltsanalyse (als Entwurf gespeichert)

Fehlgeschlagene Elemente werden als Entwürfe mit dem Originalinhalt in _importError zur Überprüfung gespeichert.

Benutzerdefinierte Quellen erstellen

Erstellen Sie eine Quelle für andere Plattformen:

import type { ImportSource } from "emdash/import";

export const mySource: ImportSource = {
	id: "my-platform",
	name: "My Platform",
	description: "Import from My Platform",
	icon: "globe",
	canProbe: true,

	async probe(url) {
		// Check if URL matches your platform
		const response = await fetch(`${url}/api/info`);
		if (!response.ok) return null;

		return {
			sourceId: "my-platform",
			confidence: "definite",
			detected: { platform: "my-platform" },
			// ...
		};
	},

	async analyze(input, context) {
		// Parse and analyze content
		// Return ImportAnalysis
	},

	async *fetchContent(input, options) {
		// Yield NormalizedItem for each content piece
		for (const item of items) {
			yield {
				sourceId: item.id,
				postType: "post",
				title: item.title,
				content: convertToPortableText(item.body),
				// ...
			};
		}
	},
};

Registrieren Sie die Quelle in Ihrer EmDash-Konfiguration:

import { mySource } from "./src/import/custom-source";

export default defineConfig({
	integrations: [
		emdash({
			import: {
				sources: [mySource],
			},
		}),
	],
});

Nächste Schritte