,

Migrere en blogg fra Ghost til WordPress med REST API

Migrere en blogg fra Ghost til WordPress med REST API

En blogg skulle flyttes fra Ghost til WordPress. Ingen import-plugin, ingen SQL-dump, ingen snarveier. Bare de to REST-API-ene og litt lim imellom. Ghost skulle dessuten slås av rett etterpå, så det var ikke rom for en andre runde: innhold, bilder og datoer måtte alt sammen over i ett strekk.

Hent innholdet fra Ghost i ett kall

Flyt fra Ghost via et script til WordPress

Det fine med Ghost Content API er at det leverer ferdig HTML. Du slipper Markdown-konvertering og egen rendering. Be om HTML og plaintext i samme slengen, og ta med tagger og forfattere mens du er der.

GET https://blogg.example.com/ghost/api/content/posts/
    ?key=CONTENT_API_KEY
    &formats=html,plaintext
    &include=tags,authors
    &limit=all

Feltet html er publiseringsklart som det er. Plaintext er kjekt å ha liggende til utdrag. Tagger og forfattere trenger du senere, når alt skal mappes mot WordPress.

Bildene må lastes opp på nytt

Her ligger den første fella. Bilde-URL-ene i Ghost-HTML-en peker til Ghost sin egen server, og den dør i det du skrur av instansen. Altså må hvert eneste bilde lastes ned, lastes opp til WordPress, og URL-en byttes ut i innholdet før posten går live.

Opplasting til media-endepunktet krever en Content-Disposition-header med filnavn. Dropper du den, får du ikke satt navnet på fila.

POST /wp-json/wp/v2/media
Content-Disposition: attachment; filename="bilde.jpg"
Content-Type: image/jpeg

<binaere bildedata>

Svaret gir deg en ny source_url. Den bytter du inn for den gamle Ghost-URL-en i HTML-en. Dette må gjøres for samtlige bilder i hver post før innholdet sendes videre. Glemmer du ett, står det og peker i tomma etterpå.

wpautop ødelegger egen HTML

Bilder lastes opp paa nytt til mediebiblioteket via API

WordPress kjører alt innhold gjennom wpautop. Filteret setter inn p og br på egen hånd, basert på hvor linjeskiftene ligger. Det høres uskyldig ut, men det brekker grid- og flex-layout, og deler opp script-blokker hver gang det finnes en blank linje.

To regler er nok til å holde innholdet i live:

  • Ikke ha blanke linjer i egen HTML. En blank linje blir til et avsnitt du aldri ba om.
  • Legg all kode i wp:code-blokker. Da lar WordPress innholdet stå urørt.
<!-- wp:code -->
<pre class="wp-block-code"><code>din kode her</code></pre>
<!-- /wp:code -->

Publiser med riktig dato

Selve publiseringen går via posts-endepunktet. Det ene feltet som virkelig teller her er date: sett den til Ghost sin originaldato. Hopper du over det, stempler WordPress alt med dagens dato, og hele kronologien på bloggen ryker på et blunk.

Tagger og kategorier må oppgis som ID-er, ikke navn. Slå opp de som finnes fra før, opprett de som mangler, og send inn listene med ID-er.

POST /wp-json/wp/v2/posts
{
  "title": "Original tittel",
  "content": "<innhold med nye bilde-URL-er>",
  "status": "publish",
  "date": "2024-11-03T09:14:00",
  "categories": [12, 45],
  "tags": [7, 19]
}

Rekkefølgen som fungerer

Oppskriften i klartekst: Hent post. Last opp bilder og bytt URL-er. Map tagger og kategorier til ID-er. Publiser med original dato. Ingen blanke linjer, all kode i wp:code. Og så, først da, slår du av Ghost.


Trenger du hjelp med dette?

Ta kontakt for en uforpliktende prat om hvordan jeg kan hjelpe deg.

Navn