Cum se programează cu Yii2 Localizare cu I18n

Ce veți crea

Dacă vă întrebați: "Ce este Yii?" verificați tutorialul meu anterior: Introducere în Cadrul Yii, care examinează beneficiile lui Yii și include o imagine de ansamblu a ceea ce este nou în Yii 2.0, lansat la 12 octombrie 2014.

În această serie de programare cu seria Yii2, îndrumăm cititorii în folosirea noii tehnologii Yii2 Framework for PHP. În prima parte, am creat Yii2 la nivel local, am construit o aplicație Hello World, am creat un server de la distanță și am folosit Github să implementeze codul nostru. În partea a doua, am aflat despre implementarea de către Yii a arhitecturii Model View Controller și despre modul de a construi pagini web și formulare care colectează și validează datele. În partea a treia, am folosit baza de date a Yii și capacitățile active de înregistrare pentru a automatiza generarea de coduri pentru o aplicație web de bază. Și, în partea a patra, am învățat cum să integrăm înregistrarea utilizatorilor.

În acest tutorial, vă voi arăta cum să utilizați suportul internațional I18n încorporat de Yii pentru a face ca aplicația dvs. să fie pregătită pentru traducerea într-un număr de limbi.

Pentru aceste exemple, vom continua să ne imaginăm că construim un cadru pentru afișarea actualizărilor de stare simple, de ex. propriul mini-Twitter.

Ce este I18n?

Potrivit Wikipedia, I18n este un numar pentru internaționalizare:

18 reprezintă numărul de litere dintre primul eu și ultimul n în internaționalizare, o utilizare inventată la DEC în anii '70 sau '80.

Cu I18n, toate șirurile de text afișate utilizatorului din aplicație sunt înlocuite de apeluri de funcții care pot încărca dinamic șiruri translate pentru orice limbă pe care utilizatorul o selectează.

Obiectivele internaționalizării

Atunci când construiți o aplicație web, este util să gândiți la nivel global de la început. Aplicația dvs. trebuie să funcționeze în alte limbi pentru utilizatorii din diferite țări? Dacă da, implementarea I18n de la început vă va economisi mult timp și dureri de cap mai târziu.

În cazul nostru, cadrul Yii oferă suport integrat pentru I18n, astfel încât este relativ ușor să construiți suport pentru I18n pe măsură ce mergeți.

Cum funcționează I18n

I18n funcționează înlocuind toate referințele la text afișate utilizatorului cu apeluri de funcții care asigură traducerea atunci când este necesar. 

De exemplu, iată ce arată numele câmpului atributului în modelul Status înainte de I18n:

funcția publicată atributLabels () return ['id' => 'ID', 'message' => 'Message', 'permissions' => 'Permissions', 'created_at' 'Actualizat la',];  

Furnizarea de versiuni traduse ale codului ar deveni foarte complicată. Traducătorii non-tehnici ar trebui să traducă codul în loc, probabil sintaxa de rupere.

Iată ce arată același cod cu I18n:

funcția publică funcțiaLabels () return 'id' => Yii :: t ('app', 'ID'), 'message' => Yii :: t ('app', ' > Yii :: t ('app', 'Permissions'), 'created_at' => Yii :: t ('app', 'Created' Actualizat la '),];  

Yii: t () este un apel pentru funcții care verifică ce limbă este selectată în prezent și afișează șirul corespunzător tradus. „Aplicația“ parametru se referă la o secțiune a aplicației noastre. Traducerile pot fi organizate opțional în funcție de diferite categorii. Dar unde apar aceste șiruri traduse??

Limba implicită, în acest caz limba engleză, este scrisă în cod, după cum se arată mai sus. Fișierele de resurse lingvistice sunt liste de tablouri de caractere ale căror cheie este textul lingvistic implicit, de ex. 'Mesaj'sau „Permisiuni“-și fiecare fișier furnizează valori text traduse pentru limba corespunzătoare.

Iată un exemplu al fișierului de traducere spaniol completat, codul de limbă "es". Yii: t () funcția folosește acest fișier pentru a găsi traducerea corespunzătoare pentru a afișa:

 'Yii Documentation', 'Yii Extensions' => 'Extensii Yii', 'Yii Documentation', 'Yii Extensions' => ' 'Yii Forum' => 'Yii Foro', 'Sigur doriți să ștergeți acest articol?' => '¿Seguro que quieres borrar este artículo?', 'Felicitări!' => 'Creare' => 'creare', 'Creare modelClass' => 'crear modelClass ',' ID '=>' identificación ',' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis exerciții de muncă ultima lucrătoare aliquip ex a commodo consequat. Duis aute irure dolor în reținerea în voluptate velit esse cillum dolore eu fugiat nulla pariatur. " => 'Lorem ipsum dolor stați amet, consecvent de adipiscare elit, nu există temporar eiusmod ut labore și dolore incididunt magna aliqua. Ut enim ad minim veniam, exercitarea quis ullamco exercita nisi ut laboris aliquip commodo ex ea consequat. "Permisi", "Reset" => "reajustar", "Căutare" = "Permisiunile" = " > 'actualización', 'actualización', 'actualización', 'actualización', 'actualizado', 'actualizado' ',' Ați creat cu succes aplicația Yii-powered '. => 'Ha creado su aplicación Yii con alimentación.';];

În timp ce acest lucru pare a consuma timp, Yii oferă scripturi pentru a automatiza generarea și organizarea acestor șabloane de fișiere.

Prin separarea textului de cod, facem mai ușoară ca experții non-tehnici multilingvi să traducă aplicațiile noastre pentru noi - fără a sparge codul.

I18n oferă, de asemenea, funcții specializate pentru traducerea timpului, valutei, plurals et al. Nu voi intra în detalii despre acestea în acest tutorial. 

Configurarea suportului I18n

Din păcate, documentația Yii2 pentru I18n nu este încă foarte descriptivă și a fost dificil să se găsească exemple pas cu pas. Din fericire pentru tine, o să te trec prin ceea ce am învățat de la spălarea documentelor și a web-ului. Am găsit exemplul I18n al Codului Ninja și Ghidul definitiv Yii2 pe I18n, iar contribuitorul Yii Alexander Makarov mi-a oferit asistență și.

Generarea fișierului de configurare I18n

Folosim șablonul de aplicație de bază Yii2 pentru aplicația demonstrativă. Acest lucru plasează codul nostru de mai jos /Salut directorul rădăcină. Fișierele de configurare ale lui Yii în / Salut / config / * sunt încărcate ori de câte ori se fac solicitări de pagină. Vom folosi scripturile mesajului I18n pentru a construi un fișier de configurare pentru I18n în comună / config cale.

Din radacina codbasei noastre, vom rula Yii Mesaj / config script:

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

Aceasta generează următorul șablon de fișier pe care îl putem personaliza:

 __DIR__, // array, required, listă de coduri de limbă pe care mesajele extrase // ar trebui să fie traduse la. De exemplu, ['zh-CN', 'de']. 'languages' => ['de'], // string, numele funcției pentru traducerea mesajelor. // Valoare implicită la 'Yii :: t'. Acesta este folosit ca un semn pentru a găsi mesajele care urmează să fie // traduse. Puteți utiliza un șir pentru numele unei singure funcții sau o matrice pentru // nume de funcții multiple. 'translator' => 'Yii :: t', // boolean, dacă doriți să sortați mesajele prin chei atunci când îmbinați mesajele noi // cu cele existente. Implicit la false, ceea ce înseamnă că mesajele noi (netranslate) // vor fi separate de cele vechi (traduse). 'sort' => false, // boolean, dacă doriți să eliminați mesajele care nu mai apar în codul sursă. // Defaults to false, ceea ce înseamnă că fiecare dintre aceste mesaje va fi închis cu o pereche de "@@" mărci. 'removeUnused' => false, // array, lista modelelor care specifică care fișiere / directoare NU trebuie procesate. // Dacă este gol sau nu, toate fișierele / directoarele vor fi procesate. // Un traseu se potrivește cu un șablon dacă conține șirul de model la sfârșitul acestuia. De exemplu, // '/ a / b' se va potrivi cu toate fișierele și directoarele care se termină cu '/ a / b'; // '* .svn' se va potrivi cu toate fișierele și directoarele al căror nume se termină cu '.svn'. // și ".svn" se vor potrivi cu toate fișierele și directoarele numite exact ".svn". // Notă, caracterele "/" dintr-un model se potrivesc atât cu "/", cât și cu "\". // Vezi descrierea helpers / FileHelper :: findFiles () pentru mai multe detalii despre regulile de potrivire a modelului. 'only' => ['* .php'], // array, lista modelelor care specifică care fișiere (nu directoare) ar trebui procesate. // Dacă este gol sau nu este setat, toate fișierele vor fi procesate. // Vă rugăm să consultați "excepție" pentru detalii despre modele. // Dacă un fișier / director se potrivește atât cu un model în "numai", și "cu excepția", acesta NU va fi procesat. 'excepție' => ['.svn', '.git', '.gitignore', '.gitkeep', '.hgignore', '.hgkeep', '/ messages',], // ' este pentru salvarea mesajelor în fișiere php. 'format' => 'php', // Director rădăcină care conține traduceri de mesaje. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messages', // boolean, dacă fișierul de mesaj trebuie suprascris cu mesajul "overwrite" => true, / * // 'db' pentru mesajele îmbinate este pentru salvarea mesajelor în baza de date. 'format' => 'db', // Componenta de conectare de utilizat. Opțional. 'db' => 'db', // Tabela de mesaje personalizate. Opțional. // 'sourceMessageTable' => '% source_message', // Numele personalizat pentru tabelul cu mesaje de traducere. Opțional. // 'messageTable' => 'Formatul de ieșire' % message ', * / / * //' po 'este pentru salvarea mesajelor în fișierele gettext po. 'format' => 'po', // director rădăcină care conține traduceri de mesaje. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messages', // Numele fișierului care va fi folosit pentru traduceri. 'catalog' => 'mesaje', // boolean, dacă fișierul de mesaj trebuie suprascris cu suprascrierea mesajelor îmbinate '=> true, * /]; 

Personalizez fișierul după cum urmează. ma mut messagePath până în partea de sus și personalizați sourcePath și messagePath. De asemenea, precizez limbile în care vreau să-mi susțin cererea în afara limbii engleze - în acest caz spaniolă, germană (italiană) și japoneză (ja). Iată o listă a tuturor codurilor de limbă I18n.

 __DIR__. DIRECTORY_SEPARATOR. '...', // Directorul rădăcină care conține traduceri de mesaje. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. "...". DIRECTORY_SEPARATOR. 'messages', // array, required, listă de coduri de limbă pe care mesajele extrase // ar trebui să fie traduse la. De exemplu, ['zh-CN', 'de']. 'languages' => ['de', 'es', 'it', 'ja'], // string, numele funcției pentru traducerea mesajelor. // Valoare implicită la 'Yii :: t'. Acesta este folosit ca un semn pentru a găsi mesajele care urmează să fie // traduse. Puteți utiliza un șir pentru numele unei singure funcții sau o matrice pentru // nume de funcții multiple. 'traducător' => 'Yii :: t', 

În pasul următor, vom executa scriptul de extragere al lui Yii, care va scana întregul cod în sourcePath copac pentru a genera fișiere de șir implicite pentru toate etichetele utilizate în codul nostru. Sunt personalizat sourcePath pentru a scana întregul arbore de cod. Sunt personalizat messagePath pentru a genera fișierele rezultate în comune / mesaje.

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

Veți vedea Yii scanând toate fișierele de cod:

Extragerea mesajelor din /Users/Jeff/Sites/hello/views/layouts/main.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/site/about.php ... Extragerea mesajelor de la / Users / Jeff / Sites / hello / views / site / contact.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/site/error.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/site/index.php... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/site/login.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/site/say.php ... Extragerea mesajelor de la / Users / Jeff / Sites / hello / views / status / _form.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/status/_search.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/status/create.php... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/status/index.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/views/status/update.php ... Extragerea mesajelor de la / Users / Jeff / Sites / hello / views / status / view.php ... Extragerea mesajelor de la / Users / Je ff / Site-uri / hello / web / index-test.php ... Extragerea mesajelor din /Users/Jeff/Sites/hello/web/index.php ... 

După ce se termină, veți vedea ceva de genul acesta în codul dvs. de bază:

Activarea I18n și selectarea unei limbi

În fișierul de configurare obișnuit, /hello/config/web.php, o să-i spunem lui Yii despre noul nostru suport lingvistic. Voi face limba spaniolă limba mea implicită:

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

Dar mai sunt încă multe de făcut. Trebuie să conștientizăm codul nostru.

Utilizând generatorul de cod Gii al lui Yii cu I18n

În partea a treia a acestei serii, am folosit baza de date a Yii și capacitățile active de înregistrare pentru a automatiza generarea de coduri. Dar nu am activat I18n, astfel încât întregul cod a avut încorporat șiruri de text. Să refacem asta.

Ne întoarcem la Gii, probabil http: // localhost: 8888 / hello / gii în browserul dvs. și re-executați generatoarele de model și controler cu I18n activat.

Iată un exemplu de generare a codului modelului Meeting cu I18n activat. Observați că specificăm "App" pentru categoria noastră de mesaje. Introducem toate șirurile de text într-un fișier de categorie de aplicații. 

Să facem același lucru pentru generația CRUD pentru controlori și vizualizări:

Dacă răsfoiți codul generat în modele, controale și vizualizări, veți vedea că șirurile de text sunt înlocuite cu Yii: t ('app', ...) funcţie:

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

titlu)?>

render ('_ căutare', ['model' => $ searchModel]); ?>

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

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

Efectuarea vizionărilor statice I18n Ready

Deoarece generăm o serie de vizualizări în aplicația noastră manuală sau în HTML, trebuie să le convertim manual pentru a folosi I18n. De exemplu, bara noastră de navigare din /views/layouts/main.php și pagina noastră de pornire în /views/site/index.php ambele trebuie să fie editate manual. 

Iată bara de navigare înainte de I18n:

NavBar :: începe (['brandLabel' => 'Compania mea', 'brandUrl' => Yii :: $ app-> homeUrl, 'opțiuni' => ['class' => 'navbar-inverse navbar ',],]); $ navItems = [['label' => 'Pagina de pornire', 'url' => ['/ site / index']], ['label' => '], [' label '=>' Despre ',' url '=> [' / site / about ']] ]]]; dacă yii :: $ app-> user-> isGuest) array_push ($ navItems, ['label' => 'Login', 'url' => [' => 'Înscrieți-vă', 'url' => ['/ user / register']]);  altceva array_push ($ navItems, ['label' => 'Logout ('. Yii :: $ app-> user-> identitate-> nume utilizator. ], 'linkOptions' => ['data-method' => 'post']]);  echo Nav :: widget (['opțiuni' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Iată bara de navigare după I18n:

NavBar :: începe (['brandLabel' => Yii :: t ('app', 'My Company'), 'brandUrl' => Yii :: $ app-> homeUrl, 'options' => > "navbar-inverse navbar-fix-top",]]]; $ navItems = [['label' => Yii :: t ('app', 'Home'), 'url' => 'app', 'Status'), 'url' => ['/ status / index']], ' '/ site / about']], ['label' => Yii :: t ('app', 'Contact'), 'url' => ['/ site / contact']]]; dacă yii :: $ app-> user-> isGuest) array_push ($ navItems, ['label' => Yii :: t ('app', 'Sign In' / login]], ['label' => Yii :: t ('app', 'Sign Up'), 'url' => ['/ user / register']]);  altceva array_push ($ navItems, ['label' => Yii :: t ('app', 'Logout' , 'url' => ['/ site / logout'], 'linkOptions' => ['data-method' => 'post']]);  echo Nav :: widget (['opțiuni' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Iată un fragment din conținutul paginii de pornire de la index.php după I18n - o mare parte din codul HTML a fost înlocuit de apelurile PHP către Yii :: t ():

»

Traducerea fișierelor dvs. de mesaje

Aruncati o privire la fisierul nostru de mesaj spaniol, /common/messages/es/frontend.php. Este o listă lungă de valori de matrice goale:

întoarcere ['Despre' => ',' Contact '=>', ' => "," Stare "=>", ... 

În scopul completării traducerilor în limba spaniolă pentru acest tutorial, voi folosi Google Translate. Drăguț, huh?

Apoi, vom face niște tăieturi și lipi cu aceste traduceri înapoi în fișierul de mesaje. 

return "['Despre' => 'Acerca de', 'Contact' => 'Contacto', 'Home' => 'Home', 'Logout' => 'Mi Empresa', 'Sign' => 'Entrar', 'Sign Up' => 'Registrarse', 'Status' => 'Estado',

Când vizităm pagina de pornire a aplicației, veți vedea versiunea spaniolă - frumos, nu?

Iată formularul Creare stare:

Dacă vreau să mă întorc în engleză, schimb doar fișierul de configurare, /config/web.php, înapoi la limba engleză:

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

Veți observa, de asemenea, pe măsură ce procedați că înlocuirea șirurilor în JavaScript are propriile sale complexități. Nu am analizat-o singură, dar extinderea Yii 1.x JsTrans poate oferi o îndrumare utilă pentru susținerea acestui lucru.

Mergând mai departe cu I18n

În cele din urmă, este posibil să dorim să traducem aplicația noastră într-un număr de limbi. Am scris un nou tutorial numit Folosirea API-ului Google Translate pentru a localiza aplicația dvs. I18n (Tuts +), care traduce automat aplicația dvs. într-o varietate de limbi. Dacă nu este publicat încă, va fi publicat în curând (consultați pagina instructorului meu). Desigur, acest lucru oferă doar traduceri de bază. Poate doriți să angajați traducători profesioniști pentru a regla fișierele ulterior.

Unele aplicații permit utilizatorilor să selecteze limba lor maternă, astfel încât atunci când se conectează, interfața cu utilizatorul se traduce automat pentru ei. În Yii, setarea $ App-> limba variabilă face acest lucru:

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

Alte aplicații, cum ar fi JScrambler.com de mai jos, utilizează calea URL pentru a schimba limbile. Utilizatorul doar face clic pe prefixul de limbă dorit, de ex. "FR", iar aplicația este tradusă automat: 

Notă: citiți introducerea mea recentă în JScrambler pentru a afla mai multe-este un serviciu destul de util.

Managerul de adrese Yii poate oferi și acest tip de funcționalitate. Voi implementa probabil aceste caracteristici într-un tutorial viitor în această serie Yii2 când mă concentrez pe Routing.

Ce urmeaza?

Sper că sunteți entuziasmat de puterea I18n și de beneficiile utilizării cadrului Yii asupra PHP vanilie. Urmăriți tutorialele viitoare în programul nostru de programare cu seria Yii2.

Dacă doriți să știți când vine următorul tutorial Yii2, urmați-mă @reifman pe Twitter sau verificați pagina de instructor. Pagina mea de instructor va include toate articolele din această serie de îndată ce vor fi publicate. De asemenea, puteți să-mi trimiteți un e-mail pe site-ul meu Lookahead Consulting.

Link-uri conexe

  • Site-ul web Yii
  • Introducere în Cadrul Yii (Tuts +)
  • Folosind API-ul Google Traducere pentru a localiza aplicația dvs. I18n (Tuts +)
  • Construirea sistemului de pornire cu PHP: Localizare cu I18n (Tuts +)
  • Alte exemple de dezvoltatori gratuite și Open Source Yii de către instructor
Cod