Come creare un'app multilingue: una demo con PHP e Gettext

Pubblicato: 2022-03-11

Che tu stia costruendo un sito Web o un'applicazione Web a tutti gli effetti, renderlo accessibile a un pubblico più ampio spesso richiede che sia disponibile in diverse lingue e locali.

Le differenze fondamentali tra la maggior parte delle lingue umane lo rendono tutt'altro che facile. Le differenze di regole grammaticali, sfumature linguistiche, formati di data e altro si combinano per rendere la localizzazione una sfida unica e formidabile.

Considera questo semplice esempio.

Le regole di pluralizzazione in inglese sono piuttosto semplici: puoi avere una forma singolare di una parola o una forma plurale di una parola.

In altre lingue, invece, come le lingue slave, ci sono due forme plurali oltre a quella singolare. Potresti anche trovare lingue con un totale di quattro, cinque o sei forme plurali, come lo sloveno, l'irlandese o l'arabo.

Il modo in cui è organizzato il codice e come sono progettati i componenti e l'interfaccia svolgono un ruolo importante nel determinare la facilità con cui è possibile localizzare l'applicazione.

L'internazionalizzazione (i18n) della tua base di codice aiuta a garantire che possa essere adattata a diverse lingue o regioni con relativa facilità. L'internazionalizzazione viene solitamente eseguita una volta, preferibilmente all'inizio del progetto per evitare di dover apportare enormi modifiche al codice sorgente lungo la strada.

Come creare un'app multilingue: una demo con PHP e Gettext

Una volta che la tua base di codice è stata internazionalizzata, la localizzazione (l10n) diventa una questione di tradurre il contenuto della tua applicazione in una lingua/locale specifica.

La localizzazione deve essere eseguita ogni volta che è necessario supportare una nuova lingua o regione. Inoltre, ogni volta che una parte dell'interfaccia (contenente testo) viene aggiornata, diventa disponibile nuovo contenuto, che quindi deve essere localizzato (cioè tradotto) in tutte le localizzazioni supportate.

In questo articolo impareremo come internazionalizzare e localizzare il software scritto in PHP. Esamineremo le varie opzioni di implementazione e i diversi strumenti a nostra disposizione per facilitare il processo.

Strumenti per l'internazionalizzazione

Il modo più semplice per internazionalizzare il software PHP è utilizzare i file array. Gli array verranno popolati con stringhe tradotte, che possono quindi essere cercate dall'interno dei modelli:

 <h1><?=$TRANS['title_about_page']?></h1>

Questo, tuttavia, non è un modo consigliato per progetti seri, poiché porrà sicuramente problemi di manutenzione in futuro. Alcuni problemi potrebbero anche apparire all'inizio, come la mancanza di supporto per l'interpolazione variabile o la pluralizzazione dei nomi e così via.

Uno degli strumenti più classici (spesso preso come riferimento per i18n e l10n) è uno strumento Unix chiamato Gettext.

Sebbene risalga al 1995, è ancora uno strumento completo per la traduzione di software che è anche facile da usare. Sebbene sia abbastanza facile iniziare, ha ancora potenti strumenti di supporto.

Gettext è ciò che useremo in questo post. Presenteremo un'ottima applicazione GUI che può essere utilizzata per aggiornare facilmente i file sorgente l10n, evitando così la necessità di gestire la riga di comando.

Biblioteche per rendere le cose facili

Principali framework Web e librerie PHP che supportano Gettext

Esistono importanti framework Web e librerie PHP che supportano Gettext e altre implementazioni di i18n. Alcuni sono più facili da installare rispetto ad altri, o sfoggiano funzionalità aggiuntive o supportano diversi formati di file i18n. Sebbene in questo documento ci concentriamo sugli strumenti forniti con il core PHP, ecco un elenco di altri degni di nota:

  • oscarotero/Gettext: supporto Gettext con un'interfaccia orientata agli oggetti; include funzioni di supporto migliorate, potenti estrattori per diversi formati di file (alcuni dei quali non supportati nativamente dal comando gettext ). Può anche esportare in formati oltre ai soli file .mo/.po, il che può essere utile se è necessario integrare i file di traduzione in altre parti del sistema, come un'interfaccia JavaScript.

  • symfony/translation: Supporta molti formati differenti, ma consiglia di usare XLIFF dettagliati. Non include funzioni di supporto o un estrattore integrato, ma supporta i segnaposto utilizzando internamente strtr() .

  • zend/i18n: supporta file array e INI o formati Gettext. Implementa un livello di memorizzazione nella cache per evitare di dover leggere il file system ogni volta. Include anche assistenti di visualizzazione e filtri e validatori di input compatibili con le impostazioni locali. Tuttavia, non ha un estrattore di messaggi.

Altri framework includono anche moduli i18n, ma quelli non sono disponibili al di fuori delle loro codebase:

  • Laravel: supporta i file array di base; non ha un estrattore automatico ma include un helper @lang per i file modello.

  • Yii: supporta la traduzione basata su array, Gettext e database e include un estrattore di messaggi. Supportato dall'estensione Intl , disponibile da PHP 5.3, e basato sul progetto ICU. Ciò consente a Yii di eseguire potenti sostituzioni, come l'ortografia di numeri, la formattazione di date, orari, intervalli, valuta e ordinali.

Se decidi di scegliere una delle librerie che non forniscono estrattori, potresti voler usare i formati Gettext, quindi puoi usare la toolchain Gettext originale (incluso Poedit) come descritto nel resto del capitolo.

Installazione di Gettext

Potrebbe essere necessario installare Gettext e la relativa libreria PHP utilizzando il gestore di pacchetti, come apt-get o yum. Dopo averlo installato, abilitalo aggiungendo extension=gettext.so (Linux/Unix) o extension=php_gettext.dll (Windows) al tuo file php.ini .

Qui useremo anche Poedit per creare file di traduzione. Probabilmente lo troverai nel gestore di pacchetti del tuo sistema; è disponibile per Unix, Mac e Windows e può essere scaricato gratuitamente anche dal suo sito Web.

Tipi di file Gettext

Ci sono tre tipi di file con cui ti occupi solitamente mentre lavori con Gettext.

I principali sono i file PO (Portable Object) e MO (Machine Object), il primo è un elenco di "oggetti tradotti" leggibili e il secondo è il binario corrispondente (da interpretare da Gettext durante la localizzazione). C'è anche un file POT (PO Template), che contiene semplicemente tutte le chiavi esistenti dai file di origine e può essere utilizzato come guida per generare e aggiornare tutti i file PO.

I file modello non sono obbligatori; a seconda dello strumento che stai utilizzando per eseguire l10n, andrai bene solo con i file PO/MO. Avrai una coppia di file PO/MO per lingua e regione, ma solo un POT per dominio.

Domini separati

Ci sono alcuni casi, in grandi progetti, in cui potrebbe essere necessario separare le traduzioni quando le stesse parole trasmettono significati diversi in contesti diversi.

In questi casi, dovrai dividerli in diversi "domini", che sono fondamentalmente chiamati gruppi di file POT/PO/MO, dove il nome del file è il suddetto dominio di traduzione .

I progetti di piccole e medie dimensioni utilizzano solitamente, per semplicità, un solo dominio; il suo nome è arbitrario, ma useremo "main" per i nostri esempi di codice.

Nei progetti Symfony, ad esempio, i domini vengono utilizzati per separare la traduzione per i messaggi di convalida.

Codice Locale

Una localizzazione è semplicemente un codice che identifica una versione di una lingua. È definito in base alle specifiche ISO 639-1 e ISO 3166-1 alpha-2: due lettere minuscole per la lingua, seguite facoltativamente da un trattino basso e due lettere maiuscole che identificano il paese o il codice regionale.

Per le lingue rare vengono utilizzate tre lettere.

Per alcuni oratori, la parte del paese può sembrare ridondante. In effetti, alcune lingue hanno dialetti in diversi paesi, come il tedesco austriaco (de_AT) o il portoghese brasiliano (pt_BR). La seconda parte serve per distinguere tra quei dialetti: quando non è presente, viene presa come una versione “generica” o “ibrida” della lingua.

Struttura della directory

Per utilizzare Gettext, dovremo aderire a una specifica struttura di cartelle.

Innanzitutto, dovrai selezionare una radice arbitraria per i tuoi file l10n nel tuo repository di origine. Al suo interno, avrai una cartella per ogni locale necessario e una cartella "LC_MESSAGES" fissa che conterrà tutte le tue coppie PO/MO.

Cartella LC_MESSAGES

Forme plurali

Come abbiamo detto nell'introduzione, lingue diverse possono avere regole di pluralizzazione diverse. Tuttavia, Gettext ci risparmia questo problema.

Quando crei un nuovo file .po, dovrai dichiarare le regole di pluralizzazione per quella lingua e i brani tradotti che sono sensibili al plurale avranno una forma diversa per ciascuna di queste regole.

Quando chiami Gettext in codice, dovrai specificare un numero relativo alla frase (es. per la frase "Hai n messaggi.", dovrai specificare il valore di n), e si risolverà la forma corretta da usare - anche usando la sostituzione di stringhe se necessario.

Le regole plurali sono composte dal numero di regole necessarie con un test booleano per ogni regola (il test per al massimo una regola può essere omesso). Per esempio:

  • Giapponese: nplurals=1; plural=0; nplurals=1; plural=0; - una regola: non esistono forme plurali

  • Inglese: nplurals=2; plural=(n != 1); nplurals=2; plural=(n != 1); - due regole: usa la forma plurale solo quando n è diverso da 1, altrimenti usa la forma singolare.

  • Portoghese brasiliano: nplurals=2; plural=(n > 1); nplurals=2; plural=(n > 1); - due regole, usa la forma plurale solo quando n è maggiore di 1, altrimenti usa la forma singolare.

Per una spiegazione più approfondita, è disponibile un tutorial informativo su LingoHub disponibile online.

Gettext determinerà quale regola utilizzare in base al numero fornito e utilizzerà la versione localizzata corretta della stringa. Per le stringhe in cui è necessario gestire la pluralizzazione, sarà necessario includere nel file .po una frase diversa per ogni regola plurale definita.

Esempio di implementazione

Dopo tutta quella teoria, diventiamo un po' pratici. Ecco un estratto di un file .po (non preoccuparti ancora troppo della sintassi, ma fatti un'idea del contenuto generale):

 msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "We're now translating some strings" msgstr "Nos estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Ola %1$s! Sua ultima visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "So uma mensagem nao lida" msgstr[1] "%d mensagens nao lidas"

La prima sezione funziona come un'intestazione, con msgid e msgstr vuoti.

Descrive la codifica dei file, le forme plurali e alcune altre cose. La seconda sezione traduce una semplice stringa dall'inglese al portoghese brasiliano e la terza fa lo stesso, ma sfrutta la sostituzione della stringa da sprintf , consentendo alla traduzione di contenere il nome utente e la data della visita.

L'ultima sezione è un esempio di forme di pluralizzazione, che mostra la versione singolare e plurale come msgid in inglese e le loro traduzioni corrispondenti come msgstr 0 e 1 (seguendo il numero dato dalla regola del plurale).

Lì viene utilizzata anche la sostituzione di stringhe, quindi il numero può essere visto direttamente nella frase, usando %d . Le forme plurali hanno sempre due msgid (singolare e plurale), quindi si consiglia di non utilizzare un linguaggio complesso come fonte di traduzione.

Chiavi di localizzazione

Come avrai notato, stiamo usando la frase inglese effettiva come ID sorgente. Quel msgid è lo stesso usato in tutti i tuoi file .po, il che significa che altre lingue avranno lo stesso formato e gli stessi campi msgid ma tradotte le righe msgstr .

Parlando di chiavi di traduzione, ci sono due approcci "filosofici" standard qui:

1. msgid come una vera frase

I principali vantaggi di questo approccio sono:

  • Se ci sono parti del software non tradotte in una determinata lingua, la chiave visualizzata manterrà comunque un significato. Ad esempio, se sai come tradurre dall'inglese allo spagnolo ma hai bisogno di aiuto per tradurre in francese, potresti pubblicare la nuova pagina con frasi francesi mancanti e parti del sito Web verrebbero invece visualizzate in inglese.

  • È molto più facile per il traduttore capire cosa sta succedendo e fare una traduzione adeguata basata su msgid .

  • Ti dà l10n "gratuito" per una lingua: quella di origine.

D'altra parte, lo svantaggio principale è che, se è necessario modificare il testo effettivo, è necessario sostituire lo stesso msgid su più file di lingua.

2. msgid come chiave univoca e strutturata

Questo descriverebbe il ruolo della frase nell'applicazione in modo strutturato, includendo il modello o la parte in cui si trova la stringa invece del suo contenuto.

Questo è un ottimo modo per organizzare il codice, separando il contenuto del testo dalla logica del modello. Tuttavia, ciò potrebbe presentare problemi al traduttore che perderebbe il contesto.

Sarebbe necessario un file della lingua di origine come base per altre traduzioni. Ad esempio, lo sviluppatore dovrebbe idealmente avere un file "en.po", che i traduttori dovrebbero leggere per capire cosa scrivere in "fr.po".

Le traduzioni mancanti visualizzerebbero sullo schermo chiavi prive di significato ("top_menu.welcome" invece di "Ciao utente!" nella suddetta pagina francese non tradotta).

Va bene in quanto costringerebbe la traduzione a essere completa prima della pubblicazione, ma negativa in quanto i problemi di traduzione sarebbero davvero terribili nell'interfaccia. Alcune librerie, tuttavia, includono un'opzione per specificare un determinato linguaggio come "fallback", con un comportamento simile all'altro approccio.

Il manuale di Gettext predilige il primo approccio in quanto, in generale, è più facile per traduttori e utenti in caso di problemi. Questo è l'approccio che useremo anche qui.

Va notato, tuttavia, che la documentazione di Symfony favorisce la traduzione basata su parole chiave, per consentire modifiche indipendenti di tutte le traduzioni senza influire anche sui modelli.

Uso quotidiano

In un'applicazione comune, utilizzeresti alcune funzioni Gettext mentre scrivi testo statico nelle tue pagine.

Tali frasi apparirebbero quindi nei file .po, verranno tradotte, compilate in file .mo e quindi utilizzate da Gettext durante il rendering dell'interfaccia effettiva. Detto questo, leghiamo insieme ciò che abbiamo discusso finora in un esempio passo dopo passo:

1. Un file modello di esempio, che include alcune chiamate gettext diverse

 <?php include 'i18n_setup.php' ?> <div> <h1><?=sprintf(gettext('Welcome, %s!'), $name)?></h1> <!-- code indented this way only for legibility → <?php if ($unread): ?> <h2> <?=sprintf( ngettext('Only one unread message', '%d unread messages', $unread), $unread )?> </h2> <?php endif ?> </div> <h1><?=gettext('Introduction')?></h1> <p><?=gettext('We\'re now translating some strings')?></p>
  • gettext() traduce semplicemente un msgid nel corrispondente msgstr per una determinata lingua. C'è anche la funzione abbreviata _() che funziona allo stesso modo

  • ngettext() fa lo stesso ma con regole plurali

  • Ci sono anche dgettext() e dngettext() , che ti consentono di sovrascrivere il dominio per una singola chiamata (ulteriori informazioni sulla configurazione del dominio nel prossimo esempio)

2. Un file di installazione di esempio (i18n_setup.php come usato sopra), selezionando la locale corretta e configurando Gettext

L'uso di Gettext comporta un po' di codice standard, ma riguarda principalmente la configurazione della directory locales e la scelta dei parametri appropriati (una locale e un dominio).

 <?php /** * Verifies if the given $locale is supported in the project * @param string $locale * @return bool */ function valid($locale) { return in_array($locale, ['en_US', 'en', 'pt_BR', 'pt', 'es_ES', 'es'); } //setting the source/default locale, for informational purposes $lang = 'en_US'; if (isset($_GET['lang']) && valid($_GET['lang'])) { // the locale can be changed through the query-string $lang = $_GET['lang']; //you should sanitize this! setcookie('lang', $lang); //it's stored in a cookie so it can be reused } elseif (isset($_COOKIE['lang']) && valid($_COOKIE['lang'])) { // if the cookie is present instead, let's just keep it $lang = $_COOKIE['lang']; //you should sanitize this! } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // default: look for the languages the browser says the user accepts $langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); }); foreach ($langs as $browser_lang) { if (valid($browser_lang)) { $lang = $browser_lang; break; } } } // here we define the global system locale given the found language putenv("LANG=$lang"); // this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance setlocale(LC_ALL, $lang); // this will make Gettext look for ../locales/<lang>/LC_MESSAGES/main.mo bindtextdomain('main', '../locales'); // indicates in what encoding the file should be read bind_textdomain_codeset('main', 'UTF-8'); // if your application has additional domains, as cited before, you should bind them here as well bindtextdomain('forum', '../locales'); bind_textdomain_codeset('forum', 'UTF-8'); // here we indicate the default domain the gettext() calls will respond to textdomain('main'); // this would look for the string in forum.mo instead of main.mo // echo dgettext('forum', 'Welcome back!'); ?>

3. Preparazione della traduzione per la prima esecuzione

Uno dei grandi vantaggi che Gettext ha rispetto ai pacchetti i18n del framework personalizzato è il suo formato di file ampio e potente.

Forse stai pensando "Oh amico, è abbastanza difficile da capire e modificare a mano, un semplice array sarebbe più facile!" Non commettere errori, applicazioni come Poedit sono qui per aiutare - molto. Puoi ottenere il programma dal loro sito Web, è gratuito e disponibile per tutte le piattaforme. È uno strumento abbastanza facile a cui abituarsi e allo stesso tempo molto potente, che utilizza tutte le funzionalità che Gettext ha a disposizione. Lavoreremo qui con l'ultima versione, Poedit 1.8.

Vista all'interno di Poedit.

Nella prima esecuzione, dovresti selezionare "File > Nuovo..." dal menu. Ti verrà richiesta la lingua; seleziona/filtra la lingua in cui vuoi tradurre o usa il formato menzionato prima, come en_US o pt_BR .

Selezione della lingua.

Ora salva il file, usando anche quella struttura di directory che abbiamo menzionato. Quindi dovresti fare clic su "Estrai dalle fonti" e qui configurerai varie impostazioni per le attività di estrazione e traduzione. Potrai trovarli tutti in seguito attraverso “Catalogo > Proprietà”:

  • Percorsi di origine: includi tutte le cartelle del progetto in cui vengono chiamati gettext() (e fratelli) - questa è solitamente la tua cartella di modelli/viste. Questa è l'unica impostazione obbligatoria.

  • Proprietà di traduzione:

    • Nome e versione del progetto, team e indirizzo e-mail del team: informazioni utili che vanno nell'intestazione del file .po.
    • Forme plurali: queste sono le regole che abbiamo menzionato prima. Puoi lasciarlo con l'opzione predefinita per la maggior parte del tempo, poiché Poedit include già un pratico database di regole plurali per molte lingue.
    • Set di caratteri: UTF-8, preferibilmente.
    • Set di caratteri del codice sorgente: il set di caratteri utilizzato dalla tua base di codice, probabilmente anche UTF-8, giusto?
  • Parole chiave di origine: il software sottostante sa come appaiono gettext() e chiamate di funzioni simili in diversi linguaggi di programmazione, ma potresti anche creare le tue funzioni di traduzione. Sarà qui che aggiungerai quegli altri metodi. Questo sarà discusso più avanti nella sezione "Suggerimenti".

Dopo aver impostato tali proprietà, Poedit eseguirà una scansione dei file di origine per trovare tutte le chiamate di localizzazione. Dopo ogni scansione, Poedit visualizzerà un riepilogo di ciò che è stato trovato e ciò che è stato rimosso dai file di origine. Le nuove voci saranno vuote nella tabella di traduzione, consentendoti di inserire le versioni localizzate di tali stringhe. Salvalo e un file .mo verrà (ri)compilato nella stessa cartella e, presto!, il tuo progetto sarà internazionalizzato!

Progetto internazionalizzato.

Poedit può anche suggerire traduzioni comuni dal web e da file precedenti. È utile, quindi devi solo verificare se hanno un senso e accettarli. Se non sei sicuro di una traduzione, puoi contrassegnarla come Fuzzy e verrà visualizzata in giallo. Le voci blu sono quelle che non hanno traduzione.

4. Traduzione di stringhe

Come avrai notato, ci sono due tipi principali di stringhe localizzate: quelle semplici e quelle con forme plurali.

Quelli semplici hanno solo due caselle: sorgente e stringa localizzata. La stringa sorgente non può essere modificata, poiché Gettext/Poedit non include la possibilità di alterare i tuoi file sorgente; piuttosto, dovrai cambiare la fonte stessa e scansionare nuovamente i file. ( Suggerimento: se fai clic con il pulsante destro del mouse su una riga di traduzione, verrà visualizzato un suggerimento con i file e le righe di origine in cui viene utilizzata quella stringa.)

Le stringhe in forma plurale includono due caselle per mostrare le due stringhe di origine e schede in modo da poter configurare le diverse forme finali.

Configurazione dei moduli finali.

Esempio di una stringa con una forma plurale su Poedit, che mostra una scheda di traduzione per ciascuna.

Ogni volta che modifichi i file del codice sorgente e devi aggiornare le traduzioni, premi semplicemente Aggiorna e Poedit eseguirà nuovamente la scansione del codice, rimuovendo le voci inesistenti, unendo quelle modificate e aggiungendone di nuove.

Poedit potrebbe anche provare a indovinare alcune traduzioni, sulla base di altre che hai fatto. Tali ipotesi e le voci modificate riceveranno un indicatore "Fuzzy", che indica che devono essere riviste, visualizzato in giallo nell'elenco.

È utile anche se hai un team di traduttori e qualcuno cerca di scrivere qualcosa di cui non è sicuro: contrassegnalo come Fuzzy e qualcun altro lo esaminerà in seguito.

Infine, si consiglia di lasciare contrassegnato "Visualizza > Voci non tradotte prima", in quanto ti aiuterà a evitare di dimenticare le voci. Da quel menu, puoi anche aprire parti dell'interfaccia utente che ti consentono di lasciare informazioni contestuali per i traduttori, se necessario.

Suggerimenti e trucchi

I server Web potrebbero finire per memorizzare nella cache i tuoi file .mo.

Se stai eseguendo PHP come modulo su Apache (mod_php), potresti riscontrare problemi con il file .mo memorizzato nella cache. Succede la prima volta che viene letto e quindi, per aggiornarlo, potrebbe essere necessario riavviare il server.

Su Nginx e PHP5 di solito sono necessari solo un paio di aggiornamenti di pagina per aggiornare la cache di traduzione e su PHP7 è raramente necessario.

Le librerie forniscono funzioni di supporto per mantenere breve il codice di localizzazione.

Come preferito da molte persone, è più facile usare _() invece di gettext() . Molte librerie i18n personalizzate dai framework usano anche qualcosa di simile a t() , per rendere più breve il codice tradotto. Tuttavia, questa è l'unica funzione che sfoggia una scorciatoia.

Potresti voler aggiungere al tuo progetto alcuni altri, come __() o _n() per ngettext() , o forse un _r() di fantasia che si unirebbe alle chiamate gettext() e sprintf() . Altre librerie, come Gettext di oscarotero, forniscono anche funzioni di supporto come queste.

In questi casi, dovrai istruire l'utilità Gettext su come estrarre le stringhe da quelle nuove funzioni. Non aver paura, è molto facile. È solo un campo nel file .po o una schermata Impostazioni in Poedit (nell'editor, quell'opzione è all'interno di "Catalogo> Proprietà> Parole chiave sorgenti").

Ricorda: Gettext conosce già le funzioni predefinite per molte lingue, quindi non preoccuparti se quell'elenco sembra vuoto. È necessario includere in tale elenco le specifiche delle nuove funzioni, seguendo questo formato specifico:

  • Se crei qualcosa come t() , che restituisce semplicemente la traduzione di una stringa, puoi specificarla come t . Gettext saprà che l'unico argomento della funzione è la stringa da tradurre;

  • Se la funzione ha più di un argomento, è possibile specificare in quale si trova la prima stringa e, se necessario, anche la forma plurale. Ad esempio, se la firma della nostra funzione è __('one user', '%d users', $number) , la specifica sarebbe __:1,2 , il che significa che il primo modulo è il primo argomento e il secondo modulo è il secondo argomento. Se invece il tuo numero viene come primo argomento, la specifica sarebbe __:2,3 , indicando che la prima forma è il secondo argomento e così via.

Dopo aver incluso queste nuove regole nel file .po, una nuova scansione introdurrà le nuove stringhe con la stessa facilità di prima.

Rendi la tua app PHP multilingue con Gettext

Gettext è uno strumento molto potente per internazionalizzare il tuo progetto PHP. Oltre alla sua flessibilità che consente il supporto per un gran numero di linguaggi umani, il suo supporto per più di 20 linguaggi di programmazione ti consente di trasferire facilmente la tua conoscenza dell'utilizzo con PHP ad altri linguaggi come Python, Java o C#.

Inoltre, Poedit può aiutare a smussare il percorso tra codice e stringhe tradotte, rendendo il processo più semplice e facile da seguire. Può anche semplificare gli sforzi di traduzione condivisa con la sua integrazione con Crowdin.

Quando possibile, considera altre lingue che i tuoi utenti potrebbero parlare. Questo è principalmente importante per i progetti non in inglese: puoi aumentare il tuo accesso utente se lo rilasci in inglese e nella tua lingua madre.

Naturalmente, non tutti i progetti hanno bisogno di internazionalizzazione, ma è molto più facile avviare i18n durante l'infanzia di un progetto, anche se inizialmente non necessario, piuttosto che farlo successivamente nel caso in cui diventasse successivamente un requisito. E con strumenti come Gettext e Poedit è più facile che mai.

Correlati: Introduzione a PHP 7: cosa c'è di nuovo e cosa non c'è più