Traduzione JSON per WordPress: Tradurre il JavaScript dell'editor a blocchi

Hai tradotto il tuo plugin. Le stringhe PHP appaiono perfettamente nelle impostazioni di amministrazione, nei template frontend, nelle notifiche email – tutto localizzato. Poi apri l'editor a blocchi, e ogni etichetta nel tuo blocco Gutenberg personalizzato è ostinatamente, beffardamente in inglese. Il pulsante "Add Item", le intestazioni del pannello ispettore, il testo segnaposto. Il tuo file .mo è caricato. Allora perché queste stringhe non vengono tradotte?
Perché da WordPress 5.0 e l'arrivo di Gutenberg, le stringhe JavaScript non provengono affatto dal tuo file .mo. Richiedono un file Traduzione JSON per WordPress completamente separato, per script – e se non lo generi, il tuo editor a blocchi rimane in inglese, indipendentemente da quanto sia completo il tuo file .po. Questo è uno dei divari di localizzazione più comuni e confusi nello sviluppo moderno di WordPress. Questa guida spiega esattamente perché succede, come funziona il sistema di traduzione JSON, i nomi dei file con hash MD5 che mandano in confusione tutti, e la toolchain completa per risolverlo.
Perché le Stringhe del Tuo Editor a Blocchi Rimangono in Inglese
Risposta breve: PHP e JavaScript usano due sistemi di consegna delle traduzioni completamente diversi in WordPress, e il tuo file .mo alimenta solo quello PHP.
Due Sistemi di Traduzione, Un Plugin
Quando WordPress esegue load_plugin_textdomain(), legge il tuo file .mo compilato nella memoria PHP. Ogni chiamata __(), _e() e _x() nel tuo codice PHP cerca lì la sua traduzione. Questo funziona perché PHP renderizza lato server – i dati .mo sono proprio lì nello stesso processo.
JavaScript è diverso. Il tuo codice blocco viene eseguito nel browser, molto tempo dopo che PHP ha terminato. Non può accedere a un file .mo lato server. Invece, il pacchetto @wordpress/i18n – l'equivalente JS di Gettext, che espone __(), _x() e sprintf() ai tuoi script – si aspetta che le traduzioni siano consegnate come un payload JSON allegato allo script specifico che le richiede.
Cosa Succede a una Stringa JS non Tradotta
Quindi un blocco con stringhe come questa:
import { __ } from '@wordpress/i18n';
registerBlockType( 'myplugin/feature-box', {
title: __( 'Feature Box', 'myplugin' ),
edit: () => {
return <Button>{ __( 'Add Item', 'myplugin' ) }</Button>;
},
} );
non troverà mai "Feature Box" o "Add Item" nel tuo file .mo, perché il browser non legge mai i file .mo. Quelle stringhe devono arrivare come JSON, collegate a questo esatto handle di script. Se non lo hai configurato, le chiamate JS __() restituiscono semplicemente l'originale inglese – in silenzio, senza errori nella console.
Collegare le Traduzioni JSON con wp_set_script_translations()
Il ponte tra il tuo script e le sue traduzioni JSON è una singola funzione PHP: wp_set_script_translations(). La risposta a "come fa WordPress a sapere quale file JSON appartiene a quale script" è: glielo dici tu, registrando lo script e poi dichiarando il suo text domain e la cartella in cui risiede il JSON.
Registrare lo Script e la Sua Cartella di Traduzione
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'
);
} );
Quando l'editor carica myplugin-editor, WordPress sa ora di cercare nella tua cartella languages/ un file JSON corrispondente a questo script e alla locale dell'utente corrente. Se ne trova uno, inietta le traduzioni prima che il tuo script venga eseguito, e le chiamate JS __() si risolvono correttamente. L'handle che passi deve corrispondere esattamente a uno script registrato – un handle non corrispondente o mancante è la seconda ragione più comune per cui le traduzioni falliscono silenziosamente.
Il Nome del File con Hash MD5 che Nessuno si Aspetta
Ecco il dettaglio che fa deragliare quasi tutti. Il file JSON che WordPress cerca non è chiamato in modo ordinato come myplugin-fr_FR.json. È nominato con un hash MD5 del percorso sorgente dello script:
Decodificare il Modello di Nome File
myplugin-fr_FR-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json
Il modello è {textdomain}-{locale}-{md5}.json, dove l'hash è l'MD5 del percorso relativo al file script (ad esempio build/index.js) come registrato. WordPress calcola questo hash in fase di runtime per trovare il JSON giusto per lo script giusto. Se nomini manualmente il tuo file, WordPress non lo troverà, e giurerai che il sistema è rotto quando sta solo cercando un nome file diverso.
Non calcoli l'hash da solo. Il comando WP-CLI i18n lo fa per te, ed è esattamente per questo che devi usare gli strumenti piuttosto che creare questi file a mano. Comprendere che l'hash esiste, tuttavia, ti fa risparmiare ore quando un file JSON è presente in languages/ ma viene comunque ignorato – è quasi sempre una mancata corrispondenza dell'hash del nome file perché il percorso dello script è cambiato.
Il Flusso di Lavoro Completo: da make-pot a make-json
La buona notizia è che mantieni le tue traduzioni negli stessi file .po che già usi. Il JSON è un artefatto derivato generato alla fine. La risposta a "devo mantenere le stringhe JS separatamente" è no – vivono nello stesso .pot/.po delle tue stringhe PHP, e un comando extra separa quelle JS in JSON.
La Pipeline a Quattro Comandi
Ecco la pipeline completa:
# 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
Il make-pot del Passaggio 1 è abbastanza intelligente da scansionare sia i tuoi file .php che la tua sorgente .js/.jsx, quindi un singolo .po per locale contiene tutto. Il make-json del Passaggio 4 legge ogni .po tradotto, trova le voci provenienti dai file JavaScript e scrive un JSON con hash corretto per ogni script. Il flag --no-purge mantiene le stringhe JS anche nel tuo .po, in modo che un successivo make-mo non le perda – senza di esso, make-json rimuove le voci JS dal .po, il che sorprende le persone che eseguono i comandi nell'ordine sbagliato.
Un file JSON generato assomiglia a un set di traduzione in formato Jed:
{
"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 legge locale_data e lo fornisce a @wordpress/i18n prima che il tuo script venga eseguito. Ora __( 'Add Item', 'myplugin' ) nel browser restituisce Ajouter un élément, e il tuo editor a blocchi è finalmente localizzato.
Come Questo Differisce dal JSON di i18next
Entrambi i sistemi usano JSON, entrambi si rivolgono a JavaScript, e questa somiglianza superficiale causa reale confusione. Non sono intercambiabili. Il JSON dell'editor a blocchi di WordPress è un payload per script derivato da Gettext, con hash MD5, consumato da @wordpress/i18n. Il JSON di i18next è un file chiave-valore piatto o annidato consumato da react-i18next o next-intl, con la sua sintassi {{interpolation}} e le sue convenzioni per le chiavi plurali.
Se stai lavorando in puro React o Next.js fuori da WordPress, vuoi l'approccio i18next, che trattiamo in tradurre il JSON di i18next in React e Next.js. All'interno di WordPress, vuoi il flusso di lavoro make-json di cui sopra. Confonderli – per esempio, scrivere a mano JSON in stile i18next piatto e aspettarsi che wp_set_script_translations() lo carichi – semplicemente non funzionerà, perché WordPress cerca il formato Jed con hash, non coppie chiave-valore arbitrarie.
Una Sorgente, Tutti i Formati di Cui Hai Bisogno
La fragilità in tutto questo è il passaggio di traduzione nel mezzo. Il tuo file .po alimenta sia il .mo (PHP) che il JSON (JavaScript), quindi una singola traduzione malfatta – un %s manipolato, un tag <strong> rotto, una forma plurale rinominata – avvelena entrambi gli output contemporaneamente. E poiché le stringhe JS vengono caricate in modo asincrono nel browser, un errore strutturale spesso si manifesta come un'etichetta vuota o un crash improvviso piuttosto che un fallback elegante.
Un Caricamento, PHP e JavaScript Coperti
È qui che una pipeline di traduzione che comprende la struttura Gettext si guadagna il suo posto. SimplePoTranslate prende un singolo file .po o .pot sorgente e produce un output pulito e tradotto in molteplici formati da un singolo caricamento – .po, .mo, .json, .php e .xliff – in modo da non dover unire strumenti separati per i tuoi livelli PHP e JavaScript. La sua Syntax Locking mantiene %s, %1$s, {count} e l'HTML inline al loro posto, il che è doppiamente importante per le stringhe dell'editor a blocchi dove un segnaposto rotto può far crollare l'intero pannello dell'editor. Approfondiamo il modello una-sorgente, molti-output in un file in ingresso, cinque formati in uscita.
Devi comunque eseguire make-json per produrre i file con hash che WordPress si aspetta – quel passaggio è specifico di WordPress e rimane nella tua build. Ma la traduzione stessa, la parte più probabile che possa rompere le tue stringhe JS, è gestita da un motore consapevole del contesto invece di uno script di ricerca e sostituzione.
Conclusione
La ragione per cui il tuo editor a blocchi rimane in inglese è strutturale, non un bug: la traduzione JSON di WordPress è un sistema di consegna separato dal file .mo, costruito specificamente perché i browser non possono leggere i dati Gettext lato server. Una volta compreso che le stringhe JavaScript necessitano di JSON con hash MD5 per script generato da wp i18n make-json e collegato con wp_set_script_translations(), la soluzione è meccanica. Mantieni le tue stringhe in un unico .po, compila il .mo per PHP ed esegui make-json per JS.
Esegui correttamente il passaggio di traduzione e entrambi gli output seguiranno. Sbaglia e passerai un pomeriggio a debuggare pannelli dell'editor vuoti.
Pronto a tradurre le tue stringhe JSON e PHP di WordPress da una singola fonte pulita? Prova SimplePoTranslate gratuitamente — nessuna carta di credito richiesta. Il livello gratuito traduce file
.poe.potreali con Syntax Locking sicura per i segnaposto, così le tue stringhe dell'editor a blocchi vengono rilasciate correttamente.