II. La localisation▲
Lorsqu'on crée un site, c'est souvent dans une optique multilangages. On parle alors d'internationalisation (i18n) et de localisation (L10n). L'internationalisation consiste à préparer une application pour la rendre potentiellement adaptée à différents langages. La localisation consiste, quant à elle, à ajouter un composant spécifique à une langue.
C'est un sujet assez complexe qui ne se limite pas à la traduction des textes, mais qui impacte aussi la représentation des dates, la gestion des pluriels, parfois la mise en page…
Qu'a à nous proposer Laravel dans ce domaine ? Nous allons le voir dans ce chapitre.
i18n parce qu'il y a 18 lettres entre le « i » et le « n » de internationalisation et L10n parce qu'il y a 10 lettres entre le « L » et le « n » de Localisation. |
II-A. Le principe▲
II-A-1. Les fichiers de langage▲
On a deux façons de gérer les langues.
II-A-1-a. Clés et valeurs▲
On a déjà parlé des fichiers de langage. Lorsque Laravel est installé, on a cette architecture :
Il n'est prévu au départ que la langue anglaise (en) avec quatre fichiers. Pour ajouter une langue, il suffit de créer un nouveau dossier : par exemple fr pour le Français.
Il faut évidemment avoir le même contenu comme nous allons le voir. |
Vous n'allez pas être obligé de faire toute cette traduction vous-même ! Certains s'en sont déjà chargés avec ce package . Nous l'avons déjà utilisé dans ce cours. |
L'application d'exemple embarque deux langues : anglais et français :
Les fichiers présents sont tous constitués exactement de la même manière. Prenons le plus léger : pagination.php. Pour l'anglais on a :
2.
3.
4.
return [
'
previous
'
=>
'
« Previous
'
,
'
next
'
=>
'
Next »
'
,
];
On voit qu'on se contente de renvoyer un tableau avec des clés et des valeurs. On ne peut pas faire plus simple ! Si on prend le même fichier en version française :
2.
3.
4.
return [
'
previous
'
=>
'
« Précédent
'
,
'
next
'
=>
'
Suivant »
'
,
];
on retrouve évidemment les mêmes clés avec des valeurs adaptées au langage.
II-A-1-b. Les textes▲
Le système clé/valeur peut devenir rapidement lourd et confus lorsqu'on a beaucoup de textes à traduire. Laravel propose une autre approche qui consiste à utiliser la traduction par défaut comme clé.
Si la langue par défaut est l'anglais, par exemple, on aura le texte anglais directement dans le code. Les autres traductions se trouveront dans des fichiers JSON.
Si vous regardez au niveau de l'application d'exemple, vous trouvez un fichier fr.json :
Ce fichier contient des éléments de ce type :
"All"
:
"Tout"
,
On a :
- All : le texte en langage par défaut présent dans le code ;
- Tout : la traduction à prévoir en français.
Les deux systèmes peuvent cohabiter et se compléter, c'est d'ailleurs le cas dans l'application d'exemple. |
II-A-2. Configuration de la locale▲
La configuration de la « locale » est effectuée dans le fichier config/app.php :
'
locale
'
=>
'
en
'
,
On peut changer cette locale en cours d'exécution si nécessaire :
App::
setLocale('
fr
'
);
Si une traduction n'est pas trouvée dans la locale actuelle, alors on va chercher la traduction de la locale par défaut définie également dans le fichier config/app.php :
'
fallback_locale
'
=>
'
en
'
,
On peut connaître la locale actuelle :
$locale
=
App::
getLocale();
et même tester si on a une certaine locale :
if (App::
isLocale('
fr
'
)) {
//
}
II-A-3. Dans le code▲
II-A-3-a. L'helper __▲
Concrètement, au niveau du code, on utilise « l'helper __ ». Il suffit de préciser la clé comme paramètre (la clé pour le système clé-valeur et le texte dans la langue d'origine pour le second système). On trouve par exemple ce code dans le contrôleur Front/PostController de l'application d'exemple :
$info
=
__('
Posts for category:
'
) .
'
<strong>
'
.
$category
->
title .
'
</strong>
'
;
Si la locale est en, c'est ce texte qui sera directement affiché. Si la locale est fr, c'est le texte correspondant qu'on trouve dans le fichier fr.json qui sera affiché :
"
Posts for category:
"
:
"
Articles pour la catégorie :
"
,
II-A-3-b. Blade▲
On peut utiliser l'helper __ dans une vue « Blade » :
{{
__('Get In Touch With Us'
) }}
mais il est plus pratique d'utiliser la directive @lang :
@lang
('Get In Touch With Us'
)
II-B. Le pluriel▲
La gestion du pluriel n'est pas toujours facile. On peut prévoir le texte du singulier et celui du pluriel séparés par le caractère « | » :
'
pommes
'
=>
'
une pomme|plusieurs pommes
'
,
On peut affiner l'affaire :
'
pommes
'
=>
'
{0} aucune pomme|[1,10] quelques pommes|[10,*] beaucoup de pommes
'
,
On utilise dans le code la fonction trans_choice. Voici un cas tiré de l'application d'exemple :
{{
trans_choice(__('comment|comments'
),
$post
->
valid_comments_count) }}
Selon la valeur de $post
->
valid_comments_count, autrement dit le nombre de commentaires valides, on prend le singulier ou le pluriel grâce à trans_choice et dans la langue voulue grâce à l'helper __.
Si on a un seul commentaire, on a le singulier :
sinon, on a le pluriel :
II-C. Des assistants▲
Pour gérer toutes ces traductions, il existe des assistants bien utiles.
Pour le système clé-valeur, voici un package intéressant :
Il permet pas mal de manipulations en ligne de commande mais se limite au premier système (clé-valeur).
Pour la gestion des fichiers « JSON » j'ai créé un package :
Il ajoute quatre commandes à Artisan :
- language:strings pour visualiser tous les textes du code (dans app et resource/views) ;
- language:make pour créer un fichier JSON pour une locale complétée avec les textes du code ;
- language:diff pour voir les différences entre une locale JSON et les textes du code ;
- language:sync pour synchroniser une locale JSON avec les textes du code.
Ce package est installé dans l'application d'exemple, vous pouvez donc directement l'utiliser.
Une approche intéressante est celle de Langly qui se présente comme une application externe :
II-D. Les noms pour la validation▲
Il y a un autre élément à prendre en compte pour la traduction : c’est le nom des contrôles de saisie. Ces noms ne sont pas visibles tant qu'il n'y a pas de souci de validation. Ils sont alors transmis dans le texte de l'erreur.
On voit mal arriver en langue française : « Le champ name est obligatoire. ». Alors comment faire ? |
Si vous regardez dans le fichier resources/lang/fr/validation.php, vous trouverez ce tableau :
'
attributes
'
=>
[
'
name
'
=>
'
Nom
'
,
'
username
'
=>
'
Pseudo
'
Ici on fait correspondre le nom d'un attribut avec sa version linguistique pour justement avoir quelque chose de cohérent au niveau du message d'erreur.
II-E. Les dates▲
Il ne vous a sans doute pas échappé que les dates et les heures ne sont pas présentées de la même manière selon la langue utilisée, en particulier entre le français et l'anglais.
En France nous utilisons le format jj/mm/aaaa alors que les Américains utilisent le format mm/jj/aaaa. De la même manière les heures sont présentées différemment. |
C'est le cas dans l'application d'exemple. Cette écriture en français :
donnera ceci en anglais :
Comment cela est-il réalisé ? |
Laravel utilise Carbon pour la gestion des dates. Carbon hérite de la classe PHP DateTime. On dispose donc de toutes les possibilités de cette classe plus toutes celles ajoutées par Carbon, et elles sont nombreuses.
Quand Eloquent récupère une date de created_at ou updated_at, il la transforme en instance Carbon. On peut modifier ce comportement, mais je n'en vois pas l'intérêt sauf cas bien particulier.
Comme la classe DataTime ne comporte pas de localisation, Carbon ajoute la méthode formatLocalized($format
) , mais pour que ça fonctionne, il faut d'abord fixer la locale avec setlocale(). Si vous regardez dans le fichier AppServiceProvider de l'application d'exemple, vous trouvez ce code :
Ensuite, dans la vue back/posts/table.blade.php :
<
td>
{{
$post
->
created_at->
formatLocalized('%c'
) }}
<
/td
>
la méthode formatLocalized fait appel à la fonction PHP strftime. C'est ainsi qu'on a la date et l'heure bien affichées pour l'anglais et le français.
Dans la vue front/post.blade.php, on trouve :
<
li class
=
"
date
"
>
{{
$post
->
created_at->
formatLocalized('%A %d %B %Y'
) }}
<
/li
>
C'est le même principe avec une autre présentation de la date.
Le but de ce chapitre est de montrer comment localiser l'interface d'une page web. S'il s'agit d'adapter le contenu selon la langue, c'est une autre histoire et il faut alors intervenir au niveau de l'URL. En effet, un principe fondamental du web veut que pour une certaine URL on renvoie toujours le même contenu. |
II-F. En résumé▲
- Laravel possède les outils de base pour la localisation.
- Laravel propose deux systèmes complémentaires : clé-valeur ou texte dans le code associé à des fichiers JSON.
- Il faut créer autant de fichiers de localisation qu'on a de langues à traiter.
- Il faut prévoir la version linguistique des attributs.
- Grâce à Carbon, la présentation des dates et heures selon la locale est simplifiée.