Utilizzare msgctxt: Aggiungere Contesto alle Traduzioni Gettext

Traduci la parola inglese "Book" in tedesco, e il tuo traduttore restituisce con sicurezza "Buch". Tre settimane dopo arriva una segnalazione di bug: il pulsante "Book a table" sul tuo modulo di prenotazione ora recita "Buch a table" - il sostantivo, non il verbo. La parola era giusta. Il contesto mancava. Questo è uno dei fallimenti silenziosi più comuni nella localizzazione del software, e la soluzione esiste in Gettext da decenni: msgctxt.
Se hai mai pubblicato una traduzione in cui una singola stringa inglese era corretta in un punto e priva di senso in un altro, hai riscontrato il problema dell'ambiguità. La stessa parola sorgente si associa a traduzioni diverse a seconda di dove appare. Senza msgctxt, il traduttore (umano o AI) non ha modo di distinguere questi casi, perché tutto ciò che vede è la stringa nuda msgid "Book". Questa guida spiega come funziona msgctxt in Gettext, come marcare il tuo codice sorgente con _x() e _ex(), come appare nei tuoi file .po, e perché una pipeline di traduzione consapevole del contesto è l'unico modo affidabile per ottenere queste stringhe correttamente su larga scala.
Il Problema dell'Ambiguità: Una Parola, Molti Significati
Il linguaggio naturale è pieno di parole che si riducono a un singolo token inglese ma si dividono in più parole in altre lingue. Il traduttore vede solo la stringa sorgente, quindi quando due elementi UI non correlati condividono la stessa parola inglese, condividono lo stesso msgid - e Gettext li unisce in un'unica voce.
Parole che si Dividono tra le Lingue
Considera tre esempi classici:
- "Book" - il sostantivo (un oggetto su uno scaffale) contro il verbo ("Book a flight", Prenotare un volo). Tedesco: Buch contro buchen.
- "Post" - pubblicare contenuti contro inviare posta. Francese: publier contro courrier.
- "Order" - una sequenza/ordinamento contro un acquisto. Spagnolo: orden contro pedido.
In inglese, il tuo codice utilizza la stessa stringa letterale in entrambi i posti:
// Somewhere in a library catalog screen
echo __( 'Book', 'mytextdomain' );
// Somewhere in a reservation form button
echo __( 'Book', 'mytextdomain' );
Come le Stringhe Identiche Collassano in un'Unica Voce
Quando esegui wp i18n make-pot o xgettext, entrambe le chiamate si riducono a un'unica voce .po:
#: catalog.php:42 reservation-form.php:88
msgid "Book"
msgstr ""
C'è esattamente una msgstr da riempire. Qualunque cosa scelga il traduttore, una delle due schermate sarà sbagliata. Il traduttore non può risolvere il problema nemmeno se lo capisce, perché il formato stesso non gli consente di fornire due traduzioni per un unico msgid. L'ambiguità è intrinseca ai dati.
Cos'è msgctxt e Come Disambigua?
msgctxt è una stringa di contesto allegata a una voce di traduzione. La risposta breve: aggiunge una seconda chiave accanto a msgid, in modo che Gettext tratti (context, msgid) come una coppia unica. Due voci con lo stesso msgid ma msgctxt diversi diventano due stringhe separate, traducibili indipendentemente.
Nel modello di ricerca di Gettext, una traduzione è normalmente indicizzata solo dalla stringa sorgente. Con msgctxt, la chiave diventa la combinazione di contesto più sorgente. Questo è l'intero meccanismo, ed è il motivo per cui funziona così pulito: non stai cambiando il testo visualizzato, solo la chiave di ricerca interna.
La Linea msgctxt in un File .po
In un file .po, il contesto appare sulla sua propria riga direttamente sopra il msgid:
#: catalog.php:42
msgctxt "noun"
msgid "Book"
msgstr "Buch"
#: reservation-form.php:88
msgctxt "verb"
msgid "Book"
msgstr "Reservieren"
Ora ci sono due voci. Hanno valori msgid identici ma valori msgctxt distinti, quindi ognuno ottiene il proprio msgstr. Il catalogo rende Buch; il pulsante di prenotazione rende Reservieren. Il runtime sceglie quello giusto perché il tuo codice gli ha detto quale contesto usare.
Confrontalo con la versione a voce singola rotta sopra. La differenza non è la qualità della traduzione - è se il modello di dati consente persino che esista la risposta corretta.
Marcare il tuo Codice: _x() e _ex()
Per emettere msgctxt nel tuo template .po, chiami una funzione di traduzione consapevole del contesto invece di quella semplice. In WordPress queste sono _x() e la sua controparte di eco _ex(); in Gettext puro si mappano a pgettext().
Scegliere tra _x() e _ex()
La semplice funzione __() accetta la stringa e il text domain. La variante contestuale inserisce il contesto come secondo argomento:
// Without context - ambiguous
__( 'Book', 'mytextdomain' );
// With context - the second argument is the msgctxt
_x( 'Book', 'noun', 'mytextdomain' ); // returns the translated string
_ex( 'Book', 'verb', 'mytextdomain' ); // echoes it directly
// Real-world disambiguation
_x( 'Post', 'verb: publish content', 'mytextdomain' );
_x( 'Post', 'noun: mail item', 'mytextdomain' );
_x( 'Order', 'sequence or sorting', 'mytextdomain' );
_x( 'Order', 'customer purchase', 'mytextdomain' );
Il secondo argomento è l'etichetta del contesto. Non viene mai mostrato ai tuoi utenti - esiste puramente per disambiguare, sia per la ricerca Gettext che per chiunque (o qualunque cosa) stia traducendo. Scrivi i contesti come brevi suggerimenti descrittivi: 'noun', 'verb', 'button label', 'admin menu'. Un contesto vago come '1' è tecnicamente valido ma inutile per un traduttore.
Quando rigeneri il template, l'estrattore riconosce queste chiamate ed emette la riga msgctxt. Strumenti come Poedit e altri editor PO raggruppano quindi visibilmente le voci per contesto, in modo che un traduttore umano veda immediatamente che "Book (sostantivo)" e "Book (verbo)" sono due lavori diversi. Se stai ancora configurando la tua toolchain di estrazione o hai problemi con l'interazione delle variabili con queste stringhe, la nostra guida su tradurre file PO senza rompere le variabili di codice copre in profondità il flusso di lavoro circostante.
Perché i Traduttori Ingenui - e Molti Strumenti AI - Sbagliano
Ecco la parte scomoda. Aggiungere msgctxt alla tua sorgente è necessario ma non sufficiente. Il contesto aiuta solo se ciò che sta traducendo lo legge effettivamente.
La Modalità di Fallimento del Contesto Scartato
Uno script di traduzione batch ingenuo fa questo: scorre le voci, prende ogni msgid, lo invia a un'API di traduzione e scrive il risultato in msgstr. Non guarda mai la riga msgctxt. Quindi, anche se hai scritto attentamente _x( 'Book', 'noun' ) e _x( 'Book', 'verb' ), lo script invia due richieste identiche - "traduci Book" - e incolla la stessa risposta in entrambe. Tutto il tuo sforzo di marcatura viene scartato all'ultimo passaggio.
Molti strumenti di traduzione AI generici hanno lo stesso punto cieco. Sono costruiti per tradurre testo, e msgctxt è metadato, non testo. Se lo strumento appiattisce il tuo .po in un elenco di stringhe prima di inviarlo al modello, il contesto non raggiunge mai il prompt del modello. Il modello, mancando di qualsiasi segnale, si basa sul senso statisticamente più comune della parola - solitamente il sostantivo per "Book", il senso di pubblicazione per "Post" - e traduce erroneamente in silenzio il caso minoritario. Non vedrai un errore. Vedrai una segnalazione di bug da un utente tedesco settimane dopo.
Contesto e Plurali Condividono la Stessa Causa Radice
Questo è anche il punto in cui la gestione dei plurali e il contesto si intersecano, perché entrambi dipendono dallo strumento che comprende la struttura di Gettext piuttosto che trattare il file come testo piatto. Se le tue stringhe coinvolgono anche forme basate sul conteggio, la stessa consapevolezza strutturale è importante - lo spieghiamo in comprendere i plurali di Gettext.
Come una Pipeline Consapevole del Contesto Usa msgctxt
Una pipeline di traduzione che rispetta msgctxt fa l'opposto dello script ingenuo. Analizza il file .po come dati strutturati, mantiene il contesto di ogni voce allegato alla sua stringa sorgente e passa quel contesto all'IA come parte del prompt - così il modello sa che sta traducendo "Book" specificamente come un verbo, non in astratto.
Il Contesto come Segnale di Prima Classe
Questo è esattamente come SimplePoTranslate affronta il problema. La sua IA consapevole del contesto legge la riga msgctxt come un segnale di prima classe: quando due voci condividono un msgid ma differiscono nel contesto, vengono tradotte come le stringhe distinte che sono effettivamente, e il suggerimento di contesto informa la scelta della parola del modello. Il risultato è che "Book (sostantivo)" torna come Buch mentre "Book (verbo)" torna come buchen o reservieren - automaticamente, senza che tu debba correggere manualmente ogni termine ambiguo.
Altrettanto importante, la pipeline conserva la riga msgctxt nell'output. Uno strumento più debole potrebbe rimuovere il contesto durante il round-trip, riducendo silenziosamente le tue due voci a una sola e reintroducendo l'ambiguità alla successiva unione. Il supporto completo a Gettext significa che il contesto sopravvive alla traduzione, alla compilazione .mo e a qualsiasi successiva reimportazione - così la tua disambiguazione è duratura, non una patch manuale una tantum. Combinato con il blocco della sintassi per i segnaposto all'interno di quelle stringhe, ottieni traduzioni che sono sia contestualmente corrette che strutturalmente intatte.
Sei ancora tu a decidere la marcatura - solo tu sai che un dato "Book" è un verbo. Ma una volta che hai annotato la tua sorgente con _x() e _ex(), una pipeline consapevole del contesto trasforma quell'annotazione in traduzioni corrette per ogni lingua target senza la necessità di supervisionare ogni singola stringa.
Conclusione
Il problema dell'ambiguità - una parola inglese, molti significati - non è una stranezza che puoi ignorare; è una caratteristica strutturale di come Gettext memorizza le stringhe. La soluzione è msgctxt: annota le stringhe ambigue nella tua sorgente con _x() e _ex(), assegna a ogni occorrenza un'etichetta di contesto chiara, e lascia che Gettext chiave la traduzione sulla coppia (context, msgid). Quella parte dipende da te, e richiede pochi minuti.
La parte più difficile è assicurarsi che il tuo passaggio di traduzione onori effettivamente quel contesto invece di buttarlo via. Script ingenui e strumenti AI solo testuali scartano msgctxt e reintroducono esattamente il bug che stavi cercando di prevenire. Una pipeline consapevole del contesto legge il contesto, traduce correttamente ogni voce disambiguata e lo preserva attraverso la compilazione e le reimportazioni.
Pronto a smettere di pubblicare traduzioni errate senza contesto? Prova SimplePoTranslate gratuitamente — non è richiesta alcuna carta di credito. Il piano gratuito gestisce file
.poe.potreali con supporto completo del contesto msgctxt, in modo che le tue stringhe disambiguate vengano tradotte correttamente la prima volta.