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 sorgente | Piattaforma | Sonda | OAuth | Importazione completa |
|---|---|---|---|---|
wxr | File export WordPress | No | No | Sì |
wordpress-com | WordPress.com | Sì | Sì | Sì |
wordpress-rest | WordPress self-hosted | Sì | No | Solo 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:
- Nell’admin WordPress, vai su Strumenti → Esporta
- Seleziona Tutti i contenuti o tipi di post specifici
- Fai clic su Scarica il file di esportazione
- Carica il file
.xmlsu EmDash
WordPress.com OAuth
Per i siti ospitati su WordPress.com, connettiti tramite OAuth per importare senza esportazioni manuali di file.
- Inserisci l’URL del tuo sito WordPress.com
- Fai clic su Connetti con WordPress.com
- Autorizza EmDash nel popup di WordPress.com
- 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:
| Stato | Significato |
|---|---|
| Ready | La collezione esiste con campi compatibili |
| New collection | Verrà creata automaticamente |
| Add fields | La collezione esiste, campi mancanti aggiunti |
| Incompatible | Conflitti di tipo campo (correzione manuale necessaria) |
Passo 3: Prepara lo schema
Fai clic su Create Schema & Import per:
- Creare nuove collezioni tramite SchemaRegistry
- Aggiungere i campi mancanti con i tipi di colonna corretti
- 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:
-
Analisi — Mostra il conteggio degli allegati per tipo
Media found: ├── Images: 75 files ├── Video: 10 files └── Other: 4 files -
Download — Streaming dagli URL WordPress con progresso
Importing media... ├── 45 of 89 (50%) ├── Current: vacation-photo.jpg └── Status: Uploading -
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
- Migrazione WordPress — Guida completa alla migrazione WordPress
- Porting dei plugin — Portare i plugin WordPress su EmDash