Come programmare con Yii2 localizzazione con I18n

Cosa starai creando

Se stai chiedendo "Cos'è Yii?" guarda il mio tutorial precedente: Introduzione al framework Yii, che rivede i vantaggi di Yii e include una panoramica delle novità di Yii 2.0, rilasciata il 12 ottobre 2014.

In questa serie di programmazione con Yii2, guido i lettori all'uso del nuovo Yii2 Framework per PHP. Nella prima parte, abbiamo configurato Yii2 localmente, creato un'applicazione Hello World, configurato un server remoto e utilizzato Github per implementare il nostro codice. Nella seconda parte, abbiamo appreso dell'implementazione di Yii della sua architettura Model View Controller e di come creare pagine Web e moduli che raccolgono e convalidano i dati. Nella terza parte, abbiamo utilizzato il database di Yii e le capacità di registrazione attive per automatizzare la generazione di codice per un'applicazione Web di base. E, nella quarta parte, abbiamo imparato come integrare la registrazione degli utenti.

In questo tutorial, ti mostrerò come utilizzare il supporto di internazionalizzazione I18n di Yii per rendere la tua applicazione pronta per la traduzione in più lingue.

Per questi esempi, continueremo a immaginare che stiamo costruendo un framework per la pubblicazione di semplici aggiornamenti di stato, ad es. il nostro mini-Twitter.

Cos'è I18n?

Secondo Wikipedia, I18n è un numero per internazionalizzazione:

18 rappresenta il numero di lettere tra il primo io e ultimo n nel internazionalizzazione, un uso coniato a DEC negli anni '70 o '80.

Con I18n, tutte le stringhe di testo visualizzate dall'utente dall'applicazione vengono sostituite da chiamate di funzione che possono caricare dinamicamente stringhe tradotte per qualsiasi lingua selezionata dall'utente.

Gli obiettivi dell'internazionalizzazione

Quando si costruisce un'applicazione Web, è utile pensare globalmente fin dall'inizio. La tua app deve funzionare in altre lingue per utenti di paesi diversi? Se è così, implementare I18n dall'inizio ti farà risparmiare un sacco di tempo e mal di testa in seguito.

Nel nostro caso, il framework Yii fornisce il supporto integrato per I18n, quindi è relativamente facile creare supporto per I18n mentre si procede.

Come funziona I18n

I18n opera sostituendo tutti i riferimenti al testo visualizzato all'utente con chiamate di funzione che forniscono la traduzione quando necessario. 

Ad esempio, ecco come appaiono i nomi dei campi degli attributi nel modello Status prima di I18n:

public function attributeLabels () return ['id' => 'ID', 'message' => 'Message', 'permissions' => 'Permessi', 'created_at' => 'Creato a', 'updated_at' => 'Aggiornato a',];  

Fornire versioni tradotte del codice diventerebbe molto complicato. I traduttori non tecnici dovrebbero tradurre il codice sul posto, probabilmente rompendo la sintassi.

Ecco come appare lo stesso codice con I18n:

public function attributeLabels () return ['id' => Yii :: t ('app', 'ID'), 'message' => Yii :: t ('app', 'Message'), 'permessi' = > Yii :: t ('app', 'Permessi'), 'created_at' => Yii :: t ('app', 'Created At'), 'updated_at' => Yii :: t ('app', ' Aggiornato a '),];  

Yii: t () è una chiamata di funzione che controlla quale lingua è attualmente selezionata e visualizza la stringa tradotta appropriata. Il 'App' parametro si riferisce ad una sezione della nostra applicazione. Le traduzioni possono essere organizzate facoltativamente secondo varie categorie. Ma dove appaiono queste stringhe tradotte?

La lingua predefinita, in questo caso l'inglese, è scritta nel codice, come mostrato sopra. I file di risorse linguistiche sono elenchi di matrici di stringhe la cui chiave è il testo della lingua predefinito, ad es. 'Messaggio'o 'permessi'-e ogni file fornisce valori di testo tradotti per la lingua appropriata.

Ecco un esempio del nostro file di traduzione spagnolo completo, il codice della lingua "es". Il Yii: t () la funzione utilizza questo file per trovare la traduzione appropriata da visualizzare:

 'Comience con Yii', 'Heading' => 'título', 'My Yii Application' => 'Mi aplicación Yii', 'Yii Documentation' => 'Yii Documentación', 'Yii Extensions' => 'Extensiones Yii', 'Yii Forum' => 'Yii Foro', 'Sei sicuro di voler eliminare questo elemento?' => '¿Seguro que quieres borrar este artículo?', 'Congratulazioni!' => '¡Enhorabuena!', 'Crea' => 'crear', 'Crea modelClass' => 'crear modelClass', 'Creato a' => 'Creado el', 'Elimina' => 'borrar ',' ID '=>' identificación ',' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed fa eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, non ha tempo néusmod ut labore et dolore incididunt magna aliqua. Ut enim ad minim veniam, nostrud quis ullamco exercitation nisi ut laboris aliquip commodo ex ea consequat. Duis Aute Irure dolor en reprehenderit en voluptate velita esse cillum dolore eu nulla fugiat pariatur. ',' Message '=>' mensaje ',' Permissions '=>' Permisos ',' Reset '=>' reajustar ',' Cerca '= > 'búsqueda', 'Statuses' => 'Los estados', 'Aggiorna' => 'actualización', 'Aggiorna modelClass:' => 'actualización modelClass:', 'Aggiornato a' => 'Attualizado A ',' Hai creato con successo la tua applicazione basata su Yii. ' => 'Ha creado su aplicación Yii con alimentación.',];

Sebbene questo aspetto richieda molto tempo, Yii fornisce script per automatizzare la generazione e l'organizzazione di questi modelli di file.

Separando il testo dal codice, per gli esperti multilingue non tecnici è più semplice tradurre le nostre applicazioni per noi, senza infrangere il codice.

I18n offre anche funzioni specializzate per la traduzione di tempo, valuta, plurali e altri. Non entrerò nel dettaglio di questi in questo tutorial. 

Configurazione del supporto I18n

Sfortunatamente, la documentazione di Yii2 per I18n non è ancora molto descrittiva ed è stato difficile trovare esempi di lavoro passo dopo passo. Fortunatamente per te, ti guiderò attraverso ciò che ho imparato dalla purga dei documenti e del web. Ho trovato utile l'esempio I18n di Code Ninja e la Guida definitiva Yii2 su I18n, e anche il collaboratore di Yii Alexander Makarov mi ha offerto assistenza.

Generazione del file di configurazione I18n

Stiamo utilizzando il modello di applicazione di base Yii2 per la nostra applicazione dimostrativa. Questo pone il nostro codice base sotto il /Ciao root directory. I file di configurazione di Yii in / Ciao / config / * vengono caricati ogni volta che vengono fatte richieste di pagina. Useremo gli script dei messaggi I18n di Yii per creare un file di configurazione per I18n in common / config sentiero.

Dalla nostra root di base di codice, eseguiremo la Yii messaggio / config script:

 ./ yii message / config @ app / config / i18n.php

Questo genera il seguente modello di file che possiamo personalizzare:

 __DIR__, // array, obbligatorio, elenco dei codici lingua a cui devono essere convertiti i messaggi // estratti. Ad esempio, ['zh-CN', 'de']. 'languages' => ['de'], // string, il nome della funzione per la traduzione dei messaggi. // Predefinito a 'Yii :: t'. Questo è usato come marchio per trovare i messaggi da // tradurre. È possibile utilizzare una stringa per il nome di una singola funzione o un array per // nomi di più funzioni. 'traduttore' => 'Yii :: t', // booleano, se ordinare i messaggi per chiave quando si uniscono nuovi messaggi // con quelli esistenti. Il valore predefinito è false, il che significa che i nuovi messaggi // non tradotti saranno separati da quelli vecchi (tradotti). 'sort' => false, // boolean, se rimuovere i messaggi che non appaiono più nel codice sorgente. // Il valore predefinito è false, il che significa che ciascuno di questi messaggi sarà incluso con una coppia di segni '@@'. 'removeUnused' => false, // array, lista di pattern che specifica quali file / directory NON devono essere elaborati. // Se vuoto o non impostato, verranno elaborati tutti i file / le directory. // Un percorso corrisponde a un modello se contiene la stringa del modello alla sua estremità. Ad esempio, // '/ a / b' corrisponderà a tutti i file e le directory che terminano con '/ a / b'; // il '* .svn' corrisponderà a tutti i file e le directory il cui nome termina con '.svn'. // e '.svn' corrisponderà a tutti i file e le directory chiamati esattamente '.svn'. // Nota, i caratteri "/" in un pattern corrispondono sia a "/" che a "\". // Vedi helper / Descrizione FileHelper :: findFiles () per ulteriori dettagli sulle regole di corrispondenza dei modelli. 'only' => ['* .php'], // array, lista di pattern che specifica quali file (non directory) devono essere elaborati. // Se vuoto o non impostato, tutti i file verranno elaborati. // Si prega di fare riferimento a "tranne" per i dettagli sui modelli. // Se un file / directory corrisponde a un pattern in "only" e "except", NON verrà elaborato. 'except' => ['.svn', '.git', '.gitignore', '.gitkeep', '.hgignore', '.hgkeep', '/ messages',], // 'php' formato di output è per salvare messaggi in file php. 'format' => 'php', // Directory principale contenente le traduzioni dei messaggi. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messages', // booleano, se il file del messaggio debba essere sovrascritto con 'overwrite' dei messaggi uniti => true, / * // 'db' formato di output serve per salvare i messaggi nel database. 'format' => 'db', // Componente di connessione da utilizzare. Opzionale. 'db' => 'db', // Tabella dei messaggi di origine personalizzata. Opzionale. // 'sourceMessageTable' => '% source_message', // Nome personalizzato per la tabella dei messaggi di traduzione. Opzionale. // 'messageTable' => '% message', * / / * // 'po' formato di output serve per salvare messaggi in file po gettext. 'format' => 'po', // Directory principale contenente le traduzioni dei messaggi. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messaggi', // Nome del file che verrà utilizzato per le traduzioni. 'catalog' => 'messages', // booleano, se il file del messaggio debba essere sovrascritto con i messaggi uniti 'overwrite' => true, * /]; 

Sto personalizzando il file come segue. Mi muovo messagePath fino alla cima e personalizzare SourcePath e messagePath. Sto anche specificando le lingue che voglio che la mia applicazione supporti oltre all'inglese, in questo caso spagnolo (es), tedesco (de), italiano (it) e giapponese (ja). Ecco una lista di tutti i codici linguistici I18n.

 __DIR__. DIRECTORY_SEPARATOR. '...', // Directory principale contenente le traduzioni dei messaggi. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. '...'. DIRECTORY_SEPARATOR. 'messaggi', // array, richiesto, elenco dei codici lingua a cui devono essere convertiti i messaggi // estratti. Ad esempio, ['zh-CN', 'de']. 'languages' => ['de', 'es', 'it', 'ja'], // string, il nome della funzione per la traduzione dei messaggi. // Predefinito a 'Yii :: t'. Questo è usato come marchio per trovare i messaggi da // tradurre. È possibile utilizzare una stringa per il nome di una singola funzione o un array per // nomi di più funzioni. 'traduttore' => 'Yii :: t', 

Nel prossimo passaggio, eseguiremo lo script di estrazione di Yii che eseguirà la scansione di tutto il codice in SourcePath albero per generare file di stringhe predefiniti per tutte le etichette utilizzate nel nostro codice. Sto personalizzando SourcePath per scansionare l'intero albero del codice. Sto personalizzando messagePath per generare i file risultanti in comuni / messaggi.

 ./ yii message / extract @ app / config / i18n.php

Vedrai Yii scansionare tutti i tuoi file di codice:

Estrazione di messaggi da /Users/Jeff/Sites/hello/views/layouts/main.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/site/about.php... Estrazione di messaggi da / Users / Jeff / Sites / ciao / views / site / contact.php ... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/site/error.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/site/index.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/site/login.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/site/say.php... Estrazione di messaggi da / Users / Jeff / Sites / ciao / views / status / _form.php ... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/status/_search.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/status/create.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/status/index.php... Estrazione di messaggi da /Users/Jeff/Sites/hello/views/status/update.php... Estrazione di messaggi da / Users / Jeff / Sites / ciao / views / status / view.php ... Estrazione di messaggi da / Users / Je ff / Sites / hello / web / index-test.php ... Estrazione di messaggi da /Users/Jeff/Sites/hello/web/index.php... 

Al termine, vedrai qualcosa di simile nella tua base di codice:

Attivare I18n e selezionare una lingua

Nel file di configurazione comune, /hello/config/web.php, parleremo a Yii del nostro nuovo supporto linguistico. Farò lo spagnolo come lingua predefinita:

 'basic', 'basePath' => dirname (__ DIR__), 'bootstrap' => ['log'], 'language' => 'es', // spanish 'components' => [ 

Ma c'è ancora molto da fare. Dobbiamo rendere il nostro codice I18n consapevole.

Utilizzando il generatore di codice Gii di Yii con I18n

Nella terza parte di questa serie, abbiamo utilizzato il database di Yii e le capacità di registrazione attiva per automatizzare la generazione del codice. Ma non abbiamo attivato I18n, quindi tutto il nostro codice includeva stringhe di testo incorporate. Rifacciamolo.

Ritorniamo a Gii, probabilmente http: // localhost: 8888 / ciao / gii nel browser, e ri-eseguire il modello e i generatori di controller con I18n attivato.

Ecco un esempio di generazione del codice del modello Meeting con I18n attivato. Si noti che specifichiamo "App" per la nostra categoria di messaggi. Stiamo inserendo tutte le nostre stringhe di testo in un unico file di categoria dell'app. 

Facciamo lo stesso per la generazione CRUD per controllori e viste:

Se sfogli il codice generato in modelli, controller e viste vedrai le stringhe di testo sostituite con Yii: t ('app', ...) funzione:

title = Yii :: t ('app', 'Statuses'); $ this-> params ['breadcrumbs'] [] = $ this-> title; ?> 

titolo)?>

render ('_ search', ['model' => $ searchModel]); ?>

'Status',]), ['create'], ['class' => 'btn btn-success'])?>

$ dataProvider, 'filterModel' => $ searchModel, 'columns' => [['class' => 'yii \ grid \ SerialColumn'], 'id', 'message: ntext', 'permessi', 'created_at', 'updated_at', ['class' => 'yii \ grid \ ActionColumn'],],]); ?>

Rendere pronte le viste statiche I18n

Poiché generiamo un numero di visualizzazioni nella nostra applicazione a mano o in HTML, è necessario convertirle manualmente per utilizzare I18n. Ad esempio, la nostra barra di navigazione in /views/layouts/main.php e la nostra home page in /views/site/index.php entrambi devono essere modificati a mano. 

Ecco la barra di navigazione prima di I18n:

NavBar :: begin (['brandLabel' => 'My Company', 'brandUrl' => Yii :: $ app-> homeUrl, 'options' => ['class' => 'navbar-inverse navbar-fixed-top ',],]); $ navItems = [['label' => 'Home', 'url' => ['/ sito / indice']], ['etichetta' => 'Stato', 'url' => ['/ stato / indice ']], [' label '=>' About ',' url '=> [' / site / about ']], [' label '=>' Contatti ',' url '=> [' / sito / contatto ']]]; if (Yii :: $ app-> user-> isGuest) array_push ($ navItems, ['label' => 'Accedi', 'url' => ['/ utente / login']], ['etichetta' => 'Registrati', 'url' => ['/ utente / registrati']]);  else array_push ($ navItems, ['label' => 'Logout ('. Yii :: $ app-> user-> identity-> username. ')', 'url' => ['/ site / logout' ], 'linkOptions' => ['data-method' => 'post']]);  echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Ecco la barra di navigazione dopo I18n:

NavBar :: begin (['brandLabel' => Yii :: t ('app', 'My Company'), 'brandUrl' => Yii :: $ app-> homeUrl, 'opzioni' => ['classe' = > 'navbar-inverse navbar-fixed-top',],]); $ navItems = [['label' => Yii :: t ('app', 'Home'), 'url' => ['/ sito / indice']], ['etichetta' => Yii :: t ( 'app', 'Status'), 'url' => ['/ status / index']], ['label' => Yii :: t ('app', 'About'), 'url' => [ '/ site / about']], ['label' => Yii :: t ('app', 'Contact'), 'url' => ['/ site / contact']]]; if (Yii :: $ app-> user-> isGuest) array_push ($ navItems, ['label' => Yii :: t ('app', 'Accedi'), 'url' => ['/ utente / login ']], [' label '=> Yii :: t (' app ',' Iscriviti '),' url '=> [' / user / register ']]);  else array_push ($ navItems, ['label' => Yii :: t ('app', 'Logout'). '('. Yii :: $ app-> utente-> identità-> nome utente. ')' , 'url' => ['/ site / logout'], 'linkOptions' => ['data-method' => 'post']]);  echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Ecco un frammento del contenuto della home page da index.php dopo I18n: gran parte dell'HTML è stato sostituito da chiamate PHP in Yii :: t ():

»

Traduzione dei file del messaggio

Dai un'occhiata al nostro file dei messaggi in spagnolo, /common/messages/es/frontend.php. È una lunga lista di valori di array vuoti:

return ['About' => ", 'Contact' =>", 'Home' => ", 'Logout' =>", 'My Company' => ", 'Accedi' =>", 'Iscriviti' => ", 'Stato' =>", ... 

Ai fini della compilazione delle traduzioni in lingua spagnola per questo tutorial, utilizzerò Google Traduttore. Ingannevole, eh?

Quindi, faremo un po 'di copia e incolla con quelle traduzioni nel file dei messaggi. 

return ['About' => 'Acerca de', 'Contact' => 'Contacto', 'Home' => 'Home', 'Logout' => 'Salir', 'My Company' => 'Mi Empresa', 'Sign In' => 'Entrar', 'Sign Up' => 'Registrarse', 'Status' => 'Estado',

Quando visiteremo la home page dell'applicazione, vedremo la versione spagnola, bella, eh?

Ecco il modulo Crea stato:

Se voglio tornare in inglese, cambio semplicemente il file di configurazione, /config/web.php, torna in inglese:

 'basic', 'basePath' => dirname (__ DIR__), 'bootstrap' => ['log'], 'language' => 'en', // back to English 'components' => [

Noterai anche mentre procedi che sostituire le stringhe in JavaScript ha le sue complessità. Non l'ho esplorato da solo, ma l'estensione JsTrans Yii 1.x può fornire utili linee guida per supportarlo.

Andando più lontano con I18n

In definitiva, potremmo voler tradurre la nostra applicazione in un certo numero di lingue. Ho scritto un nuovo tutorial chiamato Utilizzo dell'API di Google Traduttore per localizzare la tua app I18n (Tuts +) che traduce automaticamente la tua applicazione in una varietà di lingue. Se non è ancora stato pubblicato, verrà pubblicato presto (controlla la mia pagina per l'istruttore). Naturalmente, questo fornisce solo le traduzioni di base. Si consiglia di assumere traduttori professionisti per ottimizzare i file in seguito.

Alcune applicazioni consentono agli utenti di selezionare la loro lingua nativa in modo che quando si collegano, l'interfaccia utente si traduca automaticamente per loro. In Yii, impostando il $ App-> lingua variabile fa questo:

\ Yii :: $ di app> language = 'es';

Altre applicazioni, come JScrambler.com sotto, sfruttano il percorso dell'URL per cambiare lingua. L'utente fa semplicemente clic sul prefisso della lingua che desidera, ad es. "FR", e l'app è automaticamente tradotta: 

Nota: leggi la mia recente introduzione a JScrambler per saperne di più-è un servizio piuttosto utile.

L'URL Manager di Yii può fornire anche questo tipo di funzionalità. Probabilmente implementerò queste funzionalità in un futuro tutorial in questa serie Yii2 quando mi concentrerò su Routing.

Qual'è il prossimo?

Spero che tu sia entusiasta della potenza di I18n e dei vantaggi dell'utilizzo di Yii Framework rispetto a vanilla PHP. Guarda i prossimi tutorial nella nostra serie Programming with Yii2.

Se vuoi sapere quando arriverà il prossimo tutorial di Yii2, seguimi @reifman su Twitter o controlla la mia pagina di istruttore. La mia pagina di istruttore includerà tutti gli articoli di questa serie non appena saranno pubblicati. Puoi anche mandarmi una e-mail sul mio sito Web di Lookahead Consulting.

Link correlati

  • Sito Web di Yii Framework
  • Introduzione al framework Yii (Tuts +)
  • Utilizzo dell'API di Google Traduttore per localizzare la tua app I18n (Tuts +)
  • Costruire la tua startup con PHP: localizzazione con I18n (Tuts +)
  • Altri esempi di sviluppatori Yii gratuiti e open source da parte dell'istruttore