WordPress JSON-oversættelse: Oversættelse af JavaScript i blokredigeringsprogrammet

Du har oversat dit plugin. PHP-strengene vises perfekt i admin-indstillingerne, frontend-skabelonerne, e-mail-notifikationerne – alt er lokaliseret. Men når du åbner blokredigeringsprogrammet, er hver etiket i din brugerdefinerede Gutenberg-blok stædigt, hånligt på engelsk. Knappen "Add Item", overskrifterne i inspektionspanelet, pladsholderteksten. Din .mo-fil er indlæst. Så hvorfor oversættes disse strenge ikke?
Fordi JavaScript-strenge siden WordPress 5.0 og Gutenbergs ankomst overhovedet ikke kommer fra din .mo-fil. De kræver en helt separat, skript-specifik WordPress JSON-oversættelsesfil – og hvis du ikke genererer den, forbliver dit blokredigeringsprogram på engelsk, uanset hvor komplet din .po-fil er. Dette er et af de mest almindelige og forvirrende lokaliseringshuller i moderne WordPress-udvikling. Denne guide forklarer præcis, hvorfor det sker, hvordan JSON-oversættelsessystemet fungerer, de MD5-hashed filnavne, der forvirrer alle, og den komplette værktøjskæde til at løse det.
Hvorfor dine blokredigeringsstrenge forbliver engelske
Kort svar: PHP og JavaScript bruger to helt forskellige oversættelsesleveringssystemer i WordPress, og din .mo-fil forsyner kun PHP-systemet.
To oversættelsessystemer, ét plugin
Når WordPress kører load_plugin_textdomain(), læser den din kompilerede .mo-fil ind i PHP-hukommelsen. Hvert kald til __(), _e() og _x() i din PHP-kode slår dens oversættelse op der. Dette virker, fordi PHP gengiver server-side – .mo-dataene er lige der i samme proces.
JavaScript er anderledes. Din blokkode kører i browseren, længe efter PHP er færdig. Den kan ikke tilgå en server-side .mo-fil. I stedet forventer @wordpress/i18n-pakken – JS-ækvivalenten af Gettext, der eksponerer __(), _x() og sprintf() til dine skripts – at oversættelser leveres som en JSON-payload knyttet til det specifikke skript, der har brug for dem.
Hvad sker der med en uoversat JS-streng
Så en blok med strenge som denne:
import { __ } from '@wordpress/i18n';
registerBlockType( 'myplugin/feature-box', {
title: __( 'Feature Box', 'myplugin' ),
edit: () => {
return <Button>{ __( 'Add Item', 'myplugin' ) }</Button>;
},
} );
vil aldrig finde "Feature Box" eller "Add Item" i din .mo-fil, fordi browseren aldrig læser .mo-filer. Disse strenge skal ankomme som JSON, koblet til dette nøjagtige skripthåndtag. Hvis du ikke har sat det op, returnerer JS __()-kaldene simpelthen den originale engelske tekst – lydløst, uden fejl i konsollen.
Tilkobling af JSON-oversættelser med wp_set_script_translations()
Broen mellem dit skript og dets JSON-oversættelser er en enkelt PHP-funktion: wp_set_script_translations(). Svaret på spørgsmålet "hvordan ved WordPress, hvilken JSON-fil der tilhører hvilket skript" er: du fortæller det, ved at registrere skriptet og derefter erklære dets tekstdomæne og den mappe, hvor JSON-filen ligger.
Registrering af skriptet og dets oversættelsesmappe
add_action( 'init', function () {
wp_register_script(
'myplugin-editor',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
'1.0.0'
);
// Tell WordPress where this script's JSON translations live
wp_set_script_translations(
'myplugin-editor', // the registered script handle
'myplugin', // text domain
plugin_dir_path( __FILE__ ) . 'languages'
);
} );
Når redigeringsprogrammet indlæser myplugin-editor, ved WordPress nu, at den skal kigge i din languages/-mappe efter en JSON-fil, der matcher dette skript og den aktuelle brugers sprogindstilling. Hvis den finder en, injicerer den oversættelserne, før dit skript kører, og JS __()-kaldene løses korrekt. Håndtaget, du sender med, skal nøjagtigt matche et registreret skript – et forkert eller manglende håndtag er den næstmest almindelige grund til, at oversættelser lydløst fejler.
Det MD5-hashed filnavn, ingen forventer
Her er detaljen, der bringer næsten alle på afveje. Den JSON-fil, WordPress leder efter, er ikke navngivet noget pænt som myplugin-fr_FR.json. Den er navngivet med en MD5-hash af skriptets kildesti:
Afkodning af filnavnmønsteret
myplugin-fr_FR-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json
Mønsteret er {textdomain}-{locale}-{md5}.json, hvor hashen er MD5 af den relative sti til skriptfilen (f.eks. build/index.js), som den er registreret. WordPress beregner denne hash under kørsel for at finde den rigtige JSON for det rigtige skript. Hvis du navngiver din fil manuelt, finder WordPress den ikke, og du vil sværge, at systemet er ødelagt, når det bare leder efter et andet filnavn.
Du beregner ikke hashen selv. WP-CLI i18n-kommandoen gør det for dig, hvilket netop er grunden til, at du skal bruge værktøjerne i stedet for at lave disse filer manuelt. At forstå, at hashen eksisterer, er dog det, der sparer dig timer, når en JSON-fil er til stede i languages/, men stadig ignoreres – det er næsten altid en hash-uoverensstemmelse i filnavnet, fordi skriptstien ændrede sig.
Den fulde arbejdsgang: make-pot til make-json
Den gode nyhed er, at du beholder dine oversættelser i de samme .po-filer, som du allerede bruger. JSON er et afledt artefakt, der genereres til sidst. Svaret på spørgsmålet "skal jeg vedligeholde JS-strenge separat" er nej – de lever i samme .pot/.po som dine PHP-strenge, og en ekstra kommando deler JS-strengene ud i JSON.
Fire-kommando-pipelinen
Her er den komplette pipeline:
# 1. Extract ALL translatable strings (PHP and JS) into one template
wp i18n make-pot . languages/myplugin.pot
# 2. Translate languages/myplugin-fr_FR.po as usual (Poedit, AI, etc.)
# 3. Compile the .mo for PHP strings (server-side, as always)
wp i18n make-mo languages/
# 4. Generate the MD5-hashed JSON files for JS strings
wp i18n make-json languages/ --no-purge
Trin 1's make-pot er intelligent nok til at scanne både dine .php-filer og din .js/.jsx-kilde, så en enkelt .po pr. sprogindstilling indeholder alt. Trin 4's make-json læser hver oversat .po, finder de poster, der kom fra JavaScript-filer, og skriver én korrekt-hashed JSON ud pr. skript. --no-purge-flaget bevarer også JS-strengene i din .po, så en senere make-mo ikke mister dem – uden det, fjerner make-json JS-poster fra .po, hvilket overrasker folk, der kører kommandoerne i forkert rækkefølge.
En genereret JSON-fil ligner et Jed-format oversættelsessæt:
{
"translation-revision-date": "2026-06-12 10:00+0000",
"generator": "WP-CLI/2.x",
"domain": "messages",
"locale_data": {
"messages": {
"": { "domain": "messages", "lang": "fr_FR" },
"Feature Box": [ "Bloc fonctionnalité" ],
"Add Item": [ "Ajouter un élément" ]
}
}
}
WordPress læser locale_data og sender det til @wordpress/i18n, før dit skript kører. Nu returnerer __( 'Add Item', 'myplugin' ) i browseren Ajouter un élément, og dit blokredigeringsprogram er endelig lokaliseret.
Hvordan dette adskiller sig fra i18next JSON
Begge systemer bruger JSON, begge er rettet mod JavaScript, og den overfladiske lighed skaber reel forvirring. De er ikke udskiftelige. WordPress blokredigerings-JSON er en Gettext-afledt, MD5-hashed, pr. skript payload, der forbruges af @wordpress/i18n. i18next JSON er en flad eller indlejret nøgle-værdi-fil, der forbruges af react-i18next eller next-intl, med sin egen {{interpolation}}-syntaks og flertalsnøglekonventioner.
Hvis du arbejder med almindelig React eller Next.js uden for WordPress, ønsker du i18next-tilgangen, som vi dækker i oversættelse af i18next JSON i React og Next.js. Inden for WordPress ønsker du make-json-arbejdsgangen ovenfor. At blande dem sammen – for eksempel ved manuelt at skrive flade i18next-stil JSON og forvente, at wp_set_script_translations() indlæser det – vil simpelthen ikke virke, fordi WordPress leder efter det hashed Jed-format, ikke vilkårlige nøgle-værdi-par.
Én kilde, alle de formater du har brug for
Sårbarheden i alt dette er oversættelsestrinnet i midten. Din .po-fil forsyner både .mo (PHP) og JSON (JavaScript), så en enkelt mislykket oversættelse – en beskadiget %s, et ødelagt <strong>-tag, en omdøbt flertalsform – forgifter begge outputs på én gang. Og fordi JS-strenge indlæses asynkront i browseren, viser en strukturel fejl sig ofte som en tom etiket eller et hårdt crash i stedet for en elegant fallback.
Én upload, PHP og JavaScript dækket
Det er her, en oversættelsespipeline, der forstår Gettext-strukturen, kommer til sin ret. SimplePoTranslate tager én kilde-.po eller .pot og producerer ren, oversat output i flere formater fra en enkelt upload – .po, .mo, .json, .php og .xliff – så du ikke behøver at sammensætte separate værktøjer til dine PHP- og JavaScript-lag. Dens Syntaks Låsning holder %s, %1$s, {count} og inline HTML på plads, hvilket er dobbelt vigtigt for blokredigeringsstrenge, hvor en ødelagt pladsholder kan lamme hele redigeringspanelet. Vi går dybere ind i én-kilde, mange-outputs-modellen i én fil ind, fem formater ud.
Du kører stadig make-json for at producere de hashed filer, WordPress forventer – det trin er WordPress-specifikt og forbliver i dit build. Men selve oversættelsen, den del der med størst sandsynlighed ødelægger dine JS-strenge, håndteres af en kontekstbevidst motor i stedet for et find-og-erstat-skript.
Konklusion
Grunden til, at dit blokredigeringsprogram forbliver engelsk, er strukturel, ikke en fejl: WordPress JSON-oversættelse er et separat leveringssystem fra .mo-filen, specifikt bygget fordi browsere ikke kan læse server-side Gettext-data. Når du først forstår, at JavaScript-strenge kræver per-skript, MD5-hashed JSON genereret af wp i18n make-json og koblet til med wp_set_script_translations(), er løsningen mekanisk. Bevar dine strenge i én .po, kompilér .mo til PHP, og kør make-json til JS.
Gør oversættelsestrinnet rigtigt, og begge outputs følger. Gør det forkert, og du fejlsøger tomme redigeringspaneler en hel eftermiddag.
Klar til at oversætte dine WordPress JSON- og PHP-strenge fra én ren kilde? Prøv SimplePoTranslate gratis – intet kreditkort påkrævet. Den gratis plan oversætter ægte
.po- og.pot-filer med pladsholdersikker Syntaks Låsning, så dine blokredigeringsstrenge leveres korrekte.