Content Import

In questa pagina

Il sistema di importazione di EmDash utilizza un’architettura a sorgenti pluggabili. Ogni sorgente sa come sondare, analizzare e recuperare contenuti da una piattaforma specifica.

Sorgenti di importazione

ID sorgentePiattaformaSondaOAuthImportazione completa
wxrFile export WordPressNoNo
wordpress-comWordPress.com
wordpress-restWordPress self-hostedNoSolo sonda

Upload file WXR

Il metodo di importazione più completo. Carica un file di esportazione WordPress eXtended RSS (WXR) direttamente nella dashboard admin.

Funzionalità:

  • Tutti i tipi di post (inclusi quelli personalizzati)
  • Tutti i meta field
  • Bozze e post privati
  • Gerarchia completa delle tassonomie
  • Metadati degli allegati media

Come ottenere un file WXR:

  1. Nell’admin WordPress, vai su Strumenti → Esporta
  2. Seleziona Tutti i contenuti o tipi di post specifici
  3. Fai clic su Scarica il file di esportazione
  4. Carica il file .xml su EmDash

WordPress.com OAuth

Per i siti ospitati su WordPress.com, connettiti tramite OAuth per importare senza esportazioni manuali di file.

  1. Inserisci l’URL del tuo sito WordPress.com
  2. Fai clic su Connetti con WordPress.com
  3. Autorizza EmDash nel popup di WordPress.com
  4. Seleziona i contenuti da importare

Cosa è incluso:

  • Contenuti pubblicati e bozze
  • Post privati (con autorizzazione)
  • File media tramite API
  • Campi personalizzati esposti all’API REST

Sonda API REST WordPress

Quando inserisci un URL, EmDash sonda il sito per rilevare WordPress e mostrare i contenuti disponibili:

Detected: WordPress 6.4
├── Posts: 127 (published)
├── Pages: 12 (published)
└── Media: 89 files

Note: Drafts and private content require authentication
or a full WXR export.

La sonda REST è informativa. Per importazioni complete, suggerisce di caricare un file WXR o di connettersi tramite OAuth (per WordPress.com).

Flusso di importazione

Tutte le sorgenti seguono lo stesso flusso:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Connetti  │────▶│   Analizza  │────▶│   Prepara   │────▶│   Esegui    │
│  (sonda/    │     │  (controllo │     │  (crea      │     │  (importa   │
│   upload)   │     │   schema)   │     │   schema)   │     │   contenuti)│
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘

Passo 1: Connetti

Inserisci un URL da sondare o carica un file direttamente.

Il sondaggio URL esegue tutte le sorgenti registrate in parallelo. La corrispondenza con la confidenza più alta determina l’azione suggerita:

  • Sito WordPress.com → Offre connessione OAuth
  • WordPress self-hosted → Mostra istruzioni di esportazione
  • Sconosciuto → Suggerisce upload file

Passo 2: Analizza

La sorgente analizza i contenuti e verifica la compatibilità dello schema:

Post Types:
├── post (127) → posts [New collection]
├── page (12)  → pages [Existing, compatible]
├── product (45) → products [Add 3 fields]
└── revision (234) → [Skip - internal type]

Required Schema Changes:
├── Create collection: posts
├── Add fields to pages: featured_image
└── Create collection: products

Ogni tipo di post mostra il suo stato:

StatoSignificato
ReadyLa collezione esiste con campi compatibili
New collectionVerrà creata automaticamente
Add fieldsLa collezione esiste, campi mancanti aggiunti
IncompatibleConflitti di tipo campo (correzione manuale necessaria)

Passo 3: Prepara lo schema

Fai clic su Create Schema & Import per:

  1. Creare nuove collezioni tramite SchemaRegistry
  2. Aggiungere i campi mancanti con i tipi di colonna corretti
  3. Configurare le tabelle dei contenuti con gli indici

Passo 4: Esegui l’importazione

I contenuti vengono importati in sequenza:

  • Gutenberg/HTML convertito in Portable Text
  • Stato WordPress mappato allo stato EmDash
  • Autori WordPress mappati alla proprietà (authorId) e alle byline di presentazione
  • Tassonomie create e collegate
  • Blocchi riutilizzabili (wp_block) importati come Sezioni
  • Progresso mostrato in tempo reale

Comportamento dell’importazione degli autori:

  • Se una mappatura autore punta a un utente EmDash, la proprietà viene impostata su quell’utente e viene creata/riutilizzata una byline collegata per lo stesso utente.
  • Se non c’è una mappatura utente, viene creata/riutilizzata una byline ospite dall’identità dell’autore WordPress.
  • Le voci importate ricevono crediti byline ordinati, con il primo credito impostato come primaryBylineId.

Passo 5: Importazione media (opzionale)

Dopo i contenuti, importa opzionalmente i media:

  1. Analisi — Mostra il conteggio degli allegati per tipo

    Media found:
    ├── Images: 75 files
    ├── Video: 10 files
    └── Other: 4 files
  2. Download — Streaming dagli URL WordPress con progresso

    Importing media...
    ├── 45 of 89 (50%)
    ├── Current: vacation-photo.jpg
    └── Status: Uploading
  3. Riscrittura URL — I contenuti vengono automaticamente aggiornati con i nuovi URL

L’importazione dei media utilizza l’hashing dei contenuti (xxHash64) per la deduplicazione. La stessa immagine usata in più post viene memorizzata una sola volta.

Interfaccia sorgente

Le sorgenti di importazione implementano un’interfaccia standard:

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>;
}

Tipi di input

Le sorgenti accettano diversi tipi di input:

// 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 }

Output normalizzato

Tutte le sorgenti producono lo stesso formato normalizzato:

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;
}

Endpoint API

Il sistema di importazione espone questi endpoint:

Sonda URL

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

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

Restituisce la piattaforma rilevata e l’azione suggerita.

Analizza WXR

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

file: [WordPress export .xml]

Restituisce l’analisi dei tipi di post con la compatibilità dello schema.

Prepara lo schema

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

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

Crea collezioni e campi.

Esegui l’importazione

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

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

Importa i contenuti nelle collezioni specificate.

Importa media

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

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

Streaming di aggiornamenti di progresso NDJSON durante il download/upload.

Riscrivi URL

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

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

Aggiorna i contenuti Portable Text con i nuovi URL dei media.

Gestione degli errori

Errori recuperabili

  • Timeout di rete — Ritentato con backoff
  • Errore di parsing singolo elemento — Registrato, saltato, l’importazione continua
  • Errore download media — Contrassegnato per gestione manuale

Errori fatali

  • Formato file non valido — L’importazione si ferma con messaggio di errore
  • Connessione database persa — L’importazione si mette in pausa, consente il ripristino
  • Quota storage superata — L’importazione si ferma, mostra l’utilizzo

Report degli errori

Dopo l’importazione:

Import Complete

✓ 125 posts imported
✓ 12 pages imported
✓ 85 media references recorded

⚠ 2 items had warnings:
  - Post "Special Characters ñ" - title encoding fixed
  - Page "About" - duplicate slug renamed to "about-1"

✗ 1 item failed:
  - Post ID 456 - content parsing error (saved as draft)

Gli elementi falliti vengono salvati come bozze con il contenuto originale in _importError per la revisione.

Creare sorgenti personalizzate

Crea una sorgente per altre piattaforme:

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),
				// ...
			};
		}
	},
};

Registra la sorgente nella tua configurazione EmDash:

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

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

Prossimi passi