Comment programmer avec Yii2 Localisation avec I18n

Ce que vous allez créer

Si vous demandez, "Qu'est-ce que Yii?" Découvrez mon tutoriel précédent: Introduction au framework Yii, qui passe en revue les avantages de Yii et inclut un aperçu des nouveautés de Yii 2.0, publié le 12 octobre 2014.

Dans cette série de programmation avec Yii2, je guide les lecteurs dans l'utilisation du framework Yii2 pour PHP récemment mis à jour. Dans la première partie, nous avons configuré Yii2 localement, créé une application Hello World, configuré un serveur distant et utilisé Github pour déployer notre code. Dans la deuxième partie, nous avons appris comment Yii avait implémenté son architecture Model View Controller et expliqué comment créer des pages Web et des formulaires permettant de collecter et de valider des données. Dans la troisième partie, nous avons utilisé les fonctionnalités de base de données et d'enregistrement actif de Yii pour automatiser la génération de code pour une application Web de base. Et, dans la quatrième partie, nous avons appris comment intégrer l'enregistrement de l'utilisateur.

Dans ce tutoriel, je vais vous montrer comment utiliser le support d'internationalisation I18n intégré de Yii pour préparer votre application à la traduction dans plusieurs langues..

Pour ces exemples, nous allons continuer à imaginer que nous construisons un cadre pour la publication de mises à jour de statut simples, par exemple. notre propre mini-Twitter.

Qu'est-ce que c'est??

Selon Wikipedia, I18n est un numéronyme pour Internationalisation:

18 représente le nombre de lettres entre le premier je enfin n dans internationalisation, un usage inventé à DEC dans les années 1970 ou 80.

Avec I18n, toutes les chaînes de texte affichées à l’utilisateur à partir de l’application sont remplacées par des appels de fonction permettant de charger de manière dynamique les chaînes traduites pour n’importe quelle langue choisie par l’utilisateur..

Les objectifs de l'internationalisation

Lors de la création d'une application Web, il est utile de penser globalement dès le début. Votre application doit-elle fonctionner dans d'autres langues pour des utilisateurs de différents pays? Si oui, alors implémenter I18n depuis le début vous fera gagner beaucoup de temps et vous évitera des maux de tête plus tard.

Dans notre cas, le framework Yii fournit une prise en charge intégrée pour I18n, il est donc relativement facile de créer une prise en charge pour I18n au fur et à mesure..

Comment ça marche?

I18n fonctionne en remplaçant toutes les références au texte affiché à l'utilisateur par des appels de fonction qui fournissent une traduction en cas de besoin.. 

Par exemple, voici à quoi ressemblent les noms de champ d'attribut dans le modèle Status avant I18n:

fonction publique attributLabels () return ['id' => 'ID', 'message' => 'Message', 'permissions' => 'Autorisations', 'created_at' => 'Créé à', 'updated_at' => 'Mis à jour à',];  

Fournir des versions traduites du code deviendrait très compliqué. Les traducteurs non techniques devraient traduire le code en place, ce qui risquerait de briser la syntaxe.

Voici à quoi ressemble le même code avec I18n:

fonction publique attributLabels () return ['id' => Yii :: t ('app', 'ID'), 'message' => Yii :: t ('app', 'Message'), 'permissions' = > Yii :: t ('app', 'Autorisations'), 'created_at' => Yii :: t ('app', 'Créé à'), 'updated_at' => Yii :: t ('app', ' Mis à jour à '),];  

Yii: t () est un appel de fonction qui vérifie quelle langue est actuellement sélectionnée et affiche la chaîne traduite appropriée. le 'app' paramètre fait référence à une section de notre application. Les traductions peuvent être organisées en fonction de différentes catégories. Mais où apparaissent ces chaînes traduites?

La langue par défaut, dans ce cas l'anglais, est écrite dans le code, comme indiqué ci-dessus. Les fichiers de ressources linguistiques sont des listes de tableaux de chaînes dont la clé est le texte de langue par défaut, par exemple. 'Message'ou 'Autorisations'-et chaque fichier fournit des valeurs de texte traduit pour la langue appropriée.

Voici un exemple de notre fichier de traduction en espagnol complété, code de langue "es". le Yii: t () function utilise ce fichier pour trouver la traduction appropriée à afficher:

 'Comience con Yii', 'Heading' => 'título', 'Mon application Yii' => 'Mon dépliant Yii', 'Yii Documentation' => 'Yii Documentación', 'Yii Extensions' => 'Extensiones Yii', 'Yii Forum' => 'Yii Foro', 'Êtes-vous sûr de vouloir supprimer cet élément?' => '' Vous voulez emprunter cet article? ',' Félicitations! ' => '¡Enhorabuena!', 'Create' => 'crear', 'Create modelClass' => 'crear modelClass', 'Created At' => 'Creado el', 'Delete' => 'empruntar ',' ID '=>' identificación ',' Lorem ipsum dolor sit amet, consectetur elite adipisicing, a fait une incursion temporelle dans le travail et dolore magna aliqua. Tout en un minimum de poids, l’exercice de nos exercices en cours de travail, mais il n’existe que d’excellents résultats. Duis aute irure dolor in reprrehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' => 'Lorem ipsum dolor sit amet, considère l’élite, n’a pas d’impact temporel et n’a pas d’inconvénient. Il en résulte une réduction de la consommation, une perte de poids pour l’exercice physique, une perte de temps, une perte de nourriture, une autre conséquence. Duis Aute Irure dolor en reprehenderit in voluptate velita esse cillum dolore nulla fugiat pari. ',' Message '=>' mensaje ',' Permissions '=>' Permisos ',' Reset '=>' reajustar ',' Search '= > 'búsqueda', 'Statuses' => 'Los estados', 'Update' => 'actualización', 'Update modelClass:' => 'actualización modelClass:', 'Mis à jour à' => 'Actualizado A ',' Vous avez créé avec succès votre application alimentée par Yii. ' => 'Ha creado su aplicación Yii con alimentación.',];

Bien que cela prenne beaucoup de temps, Yii fournit des scripts pour automatiser la génération et l'organisation de ces modèles de fichiers..

En séparant le texte du code, nous aidons les experts multilingues non techniques à traduire nos applications pour nous, sans casser le code..

I18n offre également des fonctions spécialisées pour la traduction du temps, de la monnaie, de pluriels et al. Je n'entrerai pas dans les détails de ceux-ci dans ce tutoriel. 

Configuration du support I18n

Malheureusement, la documentation de Yii2 pour I18n n’est pas encore très descriptive et il était difficile de trouver des exemples concrets, étape par étape. Heureusement pour vous, je vais vous expliquer ce que j'ai appris en parcourant les documents et le Web. J'ai trouvé l'exemple I18n de Code Ninja et le Guide définitif Yii2 sur I18n utiles, et Alexander Makarov, contributeur de Yii, m'a également offert son aide..

Génération du fichier de configuration I18n

Nous utilisons le modèle d'application de base Yii2 pour notre application de démonstration. Cela place notre base de code en dessous de la /Bonjour répertoire racine. Les fichiers de configuration de Yii dans / bonjour / config / * sont chargés chaque fois que des demandes de page sont faites. Nous utiliserons les scripts de message I18n de Yii pour créer un fichier de configuration pour I18n dans le commun / config chemin.

Depuis notre racine de base de code, nous allons lancer le Yii message / config scénario:

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

Cela génère le modèle de fichier suivant que nous pouvons personnaliser:

 __DIR__, // array, required, liste des codes de langue dans lesquels les messages // extraits doivent être traduits. Par exemple, ['zh-CN', 'de']. 'languages' => ['de'], // string, le nom de la fonction de traduction des messages. // La valeur par défaut est 'Yii :: t'. Ceci est utilisé comme marque pour trouver les messages à // traduire. Vous pouvez utiliser une chaîne pour un seul nom de fonction ou un tableau pour // plusieurs noms de fonction. 'translator' => 'Yii :: t', // boolean, si les messages doivent être triés par clé lors de la fusion de nouveaux messages // avec les messages existants. La valeur par défaut est false, ce qui signifie que les nouveaux // messages (non traduits) seront séparés des anciens (traduits). 'sort' => false, // boolean, s'il faut supprimer les messages qui n'apparaissent plus dans le code source. // La valeur par défaut est false, ce qui signifie que chacun de ces messages sera entouré d'une paire de marques '@@'. 'removeUnused' => false, // array, liste des modèles qui spécifient quels fichiers / répertoires NE doivent PAS être traités. // Si vide ou non défini, tous les fichiers / répertoires seront traités. // Un chemin correspond à un modèle s'il contient la chaîne de modèle à sa fin. Par exemple, // '/ a / b' correspondra à tous les fichiers et répertoires se terminant par '/ a / b'; // le '* .svn' correspondra à tous les fichiers et répertoires dont le nom se termine par '.svn'. // et le '.svn' correspondra à tous les fichiers et répertoires nommés exactement '.svn'. // Remarque, les caractères '/' d'un motif correspondent à la fois à '/' et à '\'. // Voir la description de helpers / FileHelper :: findFiles () pour plus de détails sur les règles de correspondance de modèles. 'only' => ['* .php'], // array, liste de modèles spécifiant quels fichiers (et non pas les répertoires) doivent être traités. // Si vide ou non défini, tous les fichiers seront traités. // Veuillez vous référer à "sauf" pour plus de détails sur les motifs. // Si un fichier / répertoire correspond à la fois à un modèle dans "seulement" et "sauf", il ne sera PAS traité. 'sauf' => ['.svn', '.git', '.gitignore', '.gitkeep', '.hgignore', '.hgkeep', '/ messages',], // format de sortie 'php' est pour enregistrer des messages dans des fichiers php. 'format' => 'php', // répertoire racine contenant les traductions des messages. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messages', // booléen, si le fichier de messages doit être remplacé par les messages fusionnés 'écraser' => true, / * // Le format de sortie 'db' sert à enregistrer les messages dans la base de données. 'format' => 'db', // composant de connexion à utiliser. Optionnel. 'db' => 'db', // Table de messages source personnalisée. Optionnel. // 'sourceMessageTable' => '%% source_message' ', // Nom personnalisé pour la table des messages de traduction. Optionnel. // 'messageTable' => '% message', * / / * // Le format de sortie 'po' sert à enregistrer les messages dans des fichiers po gettext. 'format' => 'po', // Répertoire racine contenant les traductions des messages. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. 'messages', // Nom du fichier qui sera utilisé pour les traductions. 'catalogue' => 'messages', // booléen, si le fichier de messages doit être écrasé par les messages fusionnés 'écraser' => true, * /]; 

Je personnalise le fichier comme suit. je bouge messagePath jusqu'au sommet et personnaliser sourcePath et messagePath. Je spécifie également les langues que je souhaite utiliser dans mon application en plus de l'anglais, en l'occurrence l'espagnol (es), l'allemand (de), l'italien (le) et le japonais (ja). Voici une liste de tous les codes de langue I18n.

 __DIR__. DIRECTORY_SEPARATOR. '…', // Répertoire racine contenant les traductions des messages. 'messagePath' => __DIR__. DIRECTORY_SEPARATOR. '…'. DIRECTORY_SEPARATOR. 'messages', // tableau, obligatoire, liste des codes de langue dans lesquels les messages // extraits doivent être traduits. Par exemple, ['zh-CN', 'de']. 'languages' => ['de', 'es', 'it', 'ja'], // string, le nom de la fonction pour la traduction des messages. // La valeur par défaut est 'Yii :: t'. Ceci est utilisé comme marque pour trouver les messages à // traduire. Vous pouvez utiliser une chaîne pour un seul nom de fonction ou un tableau pour // plusieurs noms de fonction. 'traducteur' => 'Yii :: t', 

Dans l'étape suivante, nous lancerons le script d'extrait de Yii qui analysera tout le code du sourcePath tree pour générer des fichiers de chaîne par défaut pour toutes les étiquettes utilisées dans notre code. Je personnalise sourcePath pour analyser l’ensemble de l’arbre de code. Je personnalise messagePath générer les fichiers résultants dans commun / messages.

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

Vous verrez Yii analyser tous vos fichiers de code:

Extraction de messages de /Users/Jeff/Sites/hello/views/layouts/main.php… Extraction de messages de /Users/Jeff/Sites/hello/views/site/about.php… Extraction de messages de / Utilisateurs / Jeff / Sites / hello / views / site / contact.php… Extraction de messages de /Users/Jeff/Sites/hello/views/site/error.php… Extraction de messages de /Users/Jeff/Sites/hello/views/site/index.php… Extraction de messages de /Users/Jeff/Sites/hello/views/site/login.php… Extraction de messages de /Users/Jeff/Sites/hello/views/site/say.php… Extraction de messages de / Utilisateurs / Jeff / Sites / hello / views / status / _form.php… Extraction de messages de /Users/Jeff/Sites/hello/views/status/_search.php… Extraction de messages de /Users/Jeff/Sites/hello/views/status/create.php… Extraction de messages de /Users/Jeff/Sites/hello/views/status/index.php… Extraction de messages de /Users/Jeff/Sites/hello/views/status/update.php… Extraction de messages de / Utilisateurs / Jeff / Sites / hello / views / status / view.php… Extraire les messages de / Utilisateurs / Je ff / Sites / hello / web / index-test.php… Extraction de messages de /Users/Jeff/Sites/hello/web/index.php… 

Une fois terminé, vous verrez quelque chose comme ceci dans votre base de code:

Activer I18n et sélectionner une langue

Dans le fichier de configuration commun, /hello/config/web.php, nous allons parler à Yii de notre nouveau support linguistique. Je ferai de l'espagnol ma langue par défaut:

 'basic', 'basePath' => répertoire (__DIR__), 'bootstrap' => ['log'], 'language' => 'es', // espagnol 'composants' => [ 

Mais il reste encore beaucoup à faire. Nous devons rendre notre code I18n conscient.

Utilisation du générateur de code Gii de Yii avec I18n

Dans la troisième partie de cette série, nous avons utilisé les fonctionnalités de base de données et d'enregistrement actif de Yii pour automatiser la génération de code. Mais nous n'avons pas activé I18n, donc tout notre code avait des chaînes de texte incorporées. On refait ça.

Nous revenons à Gii, probablement http: // localhost: 8888 / hello / gii dans votre navigateur, puis relancez les générateurs de modèles et de contrôleurs avec I18n activé..

Voici un exemple de génération du code de modèle Meeting avec I18n activé. Notez que nous spécifions "app" pour notre catégorie de message. Nous plaçons toutes nos chaînes de texte dans un seul fichier de catégorie d'application.. 

Faisons de même pour la génération CRUD des contrôleurs et des vues:

Si vous parcourez le code généré dans les modèles, les contrôleurs et les vues, les chaînes de texte remplacées par Yii: t ('app',…) une fonction:

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

titre)?>

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

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

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

Préparer les vues statiques I18n

Parce que nous générons plusieurs vues dans notre application manuellement ou en HTML, nous devons les convertir manuellement pour utiliser I18n. Par exemple, notre barre de navigation dans /views/layouts/main.php et notre page d'accueil /views/site/index.php les deux doivent être édités à la main. 

Voici la barre de navigation avant I18n:

NavBar :: begin (['brandLabel' => 'Ma société', 'brandUrl' => Yii :: $ app-> homeUrl, 'options' => ['class' => 'navbar-inverse navbar-fixed-top ',],]); $ navItems = [['label' => 'Home', 'url' => ['/ site / index']], ['label' => 'Status', 'url' => ['/ status / index ']], [' label '=>' À propos ',' url '=> [' / site / sur ']], [' label '=>' Contact ',' url '=> [' / site / contact ']]]; if (Yii :: $ app-> user-> isGuest) array_push ($ navItems, ['label' => 'Connexion', 'url' => ['/ user / login']], ['label' => 'Inscription', 'url' => ['/ utilisateur / registre']]);  else array_push ($ navItems, ['label' => 'Logout ('. Yii :: $ app-> utilisateur-> identité-> nom d'utilisateur. ')', 'url' => ['/ site / logout' ], 'linkOptions' => ['data-method' => 'post']]);  echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Voici la barre de navigation après I18n:

NavBar :: begin (['brandLabel' => Yii :: t ('app', 'Ma société'), 'brandUrl' => Yii :: $ app-> homeUrl, 'options' => ['class' = > 'navbar-inverse navbar-fixed-top',],]); $ navItems = [['label' => Yii :: t ('app', 'Home'), 'url' => ['/ site / index']], ['label' => 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', 'Connexion'), 'url' => ['/ user / login ']], [' label '=> Yii :: t (' app ',' Sign Up '),' url '=> [' / user / register ']]);  else array_push ($ navItems, ['label' => Yii :: t ('app', 'Logout'). '('. Yii :: $ app-> utilisateur-> identité-> nom d'utilisateur. ')' , 'url' => ['/ site / logout'], 'linkOptions' => ['data-method' => 'post']];  echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ navItems,]); NavBar :: end ();

Voici un fragment du contenu de la page d'accueil de index.php après qu'I18n ait été remplacé par des appels PHP à Yii :: t ():

»

Traduire vos fichiers de messages

Consultez notre fichier de messages en espagnol, /common/messages/es/frontend.php. C'est une longue liste de valeurs de tableau vides:

return ['About' => ", 'Contact' =>", 'Home' => ", 'Logout' =>", 'Ma société' => ", 'Connexion' =>", 'S'inscrire' => ", 'Statut' =>",… 

Afin de compléter nos traductions en espagnol pour ce tutoriel, je vais utiliser Google Translate. Tricky, hein?

Ensuite, nous ferons du copier-coller avec ces traductions dans le fichier de messages.. 

return ['About' => 'Acerca de', 'Contact' => 'Contacto', 'Home' => 'Home', 'Logout' => 'Salir', 'Ma société' => 'Mi Empresa', 'Sign In' => 'Entrar', 'Sign Up' => 'Registrarse', 'Status' => 'Estado',

Lorsque nous visiterons la page d'accueil de l'application, vous verrez la version espagnole: sympa, hein?

Voici le formulaire de création de statut:

Si je veux repasser en anglais, je modifie simplement le fichier de configuration, /config/web.php, retour en anglais:

 'basic', 'basePath' => dirname (__ DIR__), 'bootstrap' => ['log'], 'language' => 'en', // retour à l'anglais 'components' = => [

Vous remarquerez également au fur et à mesure que vous procédez que le remplacement de chaînes en JavaScript a ses propres complexités. Je ne l’ai pas exploré moi-même, mais l’extension Yii 1.x JsTrans peut servir de guide utile pour soutenir cette.

Aller plus loin avec I18n

En fin de compte, nous voudrons peut-être traduire notre application dans un certain nombre de langues. J'ai écrit un nouveau didacticiel intitulé Utilisation de l'API Google Translate pour localiser votre application I18n (Tuts +), qui traduit automatiquement votre application dans diverses langues. Si ce n'est pas encore publié, il le sera bientôt (voir la page de mon instructeur). Bien sûr, cela ne fournit que des traductions de base. Vous voudrez peut-être engager des traducteurs professionnels pour ajuster les fichiers par la suite.

Certaines applications permettent aux utilisateurs de sélectionner leur langue maternelle afin que, lorsqu'ils se connectent, l'interface utilisateur traduise automatiquement pour eux. Dans Yii, régler le $ app-> langue la variable fait ceci:

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

D'autres applications, telles que JScrambler.com ci-dessous, exploitent le chemin de l'URL pour changer de langue. L’utilisateur clique simplement sur le préfixe de la langue qu’il souhaite, par exemple. "FR", et l'application est automatiquement traduite: 

Remarque: lisez ma récente introduction à JScrambler pour en savoir plus.-c'est un service très utile.

Le gestionnaire d'URL de Yii peut également fournir ce type de fonctionnalité. Je vais probablement implémenter ces fonctionnalités dans un futur tutoriel de cette série Yii2 lorsque je me concentrerai sur le routage..

Et après?

J'espère que vous êtes enthousiasmé par la puissance d'I18n et par les avantages de l'utilisation du framework Yii par rapport à PHP vanilla. Surveillez les prochains tutoriels dans notre série Programmation avec Yii2..

Si vous souhaitez savoir quand le prochain tutoriel Yii2 arrive, suivez-moi @reifman sur Twitter ou consultez ma page d'instructeur. Ma page d'instructeur comprendra tous les articles de cette série dès leur publication. Vous pouvez également m'envoyer un email sur mon site web Lookahead Consulting.

Liens connexes

  • Yii Framework Site
  • Introduction au framework Yii (Tuts +)
  • Utilisation de l'API Google Translate pour localiser votre application I18n (Tuts +)
  • Construire votre startup avec PHP: Localisation avec I18n (Tuts +)
  • Autres exemples de développeurs Yii gratuits et à code source ouvert par l'instructeur