Un site multilingue avec GetText
Avez-vous déjà essayé de créer un site multilingue ? Si oui, comment ?
La façon la plus prisée des développeurs est de créer un fichier contenant uniquement des variables (ou constantes comme c'est le cas sur phpBB) dont les valeurs correspondent à des expressions prédéfinies.
Un exemple basique :
Code : PHP1
2
3
4 | <?php
$message_bienvenue = "Bienvenue sur mon site !";
$message_connexion = "Vous êtes désormais connecté...";
?>
|
Le fichier est ensuite enregistré dans un dossier
/lang/fr/. Puis le programmeur code quelques autres fichiers avec des noms de variables identiques mais contenant des valeurs traduites ("Welcome to my site !", "Now you're logged in...") et les enregistre dans d'autres dossiers :
/lang/en,
/lang/de/, etc. Il ne lui reste plus qu'à implémenter un script permettant de récupérer le langage préféré de l'utilisateur et en fonction du résultat, inclure le fichier de langue correspondant.
Cette méthode a l'avantage d'être relativement simple à mettre en place ; cependant, vous constaterez rapidement que
plus votre site grandira, plus vos fichiers de langue deviendront conséquents, et qui dit fichier plus conséquent dit fichier plus lourd, entraînant un ralentissement du temps d'exécution. Elle est donc réservée aux "petits" sites.
Mais si vraiment vous sentez que votre projet comportera beaucoup, beaucoup de texte à traduire, l'utilisation de la bibliothèque
Gettext (GNU) sera préférable. C'est cette bibliothèque très utile mais peu connue des développeurs en herbe que je compte vous apprendre à manier dans ce tutoriel.
Ready ? Let's go !
GetText ? Quésaco ?
Comme je l'ai mentionné en introduction,
GetText est une bibliothèque
GNU. Considérée comme une "
bibliothèque d'internationalisation", elle a été créée dans le but de faciliter la traduction de programmes et ainsi, d'en améliorer "l'exportation". J'entends par là une meilleure compréhension des utilisateurs. En effet, l'anglais est une langue très, très utilisée en informatique (et pas qu'en informatique d'ailleurs), car étant mondialement reconnue, elle facilite les échanges entre développeurs de différents horizons. Mais qu'en est-il des petits utilisateurs comme nous qui comprenons un mot sur cinq ?

C'est la question que se sont posé des programmeurs de GNU et pour y remédier, ils ont créé
GetText, un "outil" permettant de
traduire plus facilement des programmes en fonction de la langue de l'utilisateur.
Par chance,
GetText est utilisable avec PHP ! Vous voyez où je veux en venir ?
GetText utilise des fichiers compilés
.mo qui contiennent des couples
clé - valeur, la clé représentant l'expression initiale (celle que vous écrirez dans votre code) et la valeur, la traduction correspondante (celle qui sera affichée à l'utilisateur). Pour obtenir ces fichiers
.mo il nous faudra compiler des fichiers
.po que nous aurons préalablement codés.
GetText étant initialement destinée aux systèmes Unix, je demande aux utilisateurs de Windows de télécharger la dernière version de la librairie
sur ce site. Ne possédant pas moi-même cet OS, je n'ai aucune idée de la manière de l'installer. N'hésitez pas à me contacter par MP ou via les commentaires si vous avez la solution. Je me ferai une joie d'éditer mon tutoriel.
Pour les utilisateurs de Debian, je viens de dénicher un petit tutoriel abordant l'installation de
GetText ici.
Activation de GetText en local
Avant toute chose, il faut s'assurer que GetText est bien activée en local (car c'est bien évidemment en local que nous ferons nos tests). Pour cela, lancez votre serveur et créez un nouveau fichier PHP :
Code : PHP
Enregistrez le fichier à l'endroit où vous mettez tous vos scripts et exécutez-le dans votre navigateur.
Cherchez ensuite la ligne suivante :
Dans la plupart des cas, GetText sera activée (
enabled) mais si ce n'est pas le cas (
disabled), ouvrez le fichier de configuration
php.ini et supprimez le ";" devant la ligne :
extension=gettext.so
Si tout va bien, continuons.
Pour commencer, je vais vous demander de créer quelques dossiers qui contiendront les fichiers de langue. Créons d'abord un dossier
locale à la racine de notre projet. Dans ce répertoire, créez ensuite quelques dossiers correspondant chacun à une langue et veillez à ce que les noms de ces dossiers respectent le format
fr_FR. Dans le cadre de ce tutoriel, je vais en créer trois :
fr_FR,
en_US et
de_DE. Pour finir, créez, dans chacun de ces dossiers, un dossier
LC_MESSAGES. Le dossier
LC_MESSAGES contiendra le fichier final. Si vous avez bien suivi, vous devriez vous retrouver avec cette arborescence :
dossier racine
--- locale
------ fr_FR
--------- LC_MESSAGES
------ en_US
--------- LC_MESSAGES
------ de-DE
--------- LC_MESSAGES
Le dossier
en_US contiendra les expressions françaises et les traductions anglaises qui leur sont associées, le dossier
de_DE contiendra les traductions allemandes et le dossier
fr_FR contiendra les expressions françaises. Quel intérêt d'avoir des traductions françaises ? me direz-vous. C'est tout simplement pour pouvoir revenir à la version française si le site utilise un fichier de langue étranger.
Avoir des dossiers c'est bien. Encore faut-il les remplir.

Pas de panique, le chapitre suivant s'en occupe...
Création
Comme je l'ai dit dans la première partie, GetText utilise des fichiers
.mo qui contiennent des couples
clé - valeur. Les fichiers
.mo sont des fichiers
.po compilés.

Dans ce tutoriel, je vais considérer que la langue initiale de mon site est le français. Les clés correspondront donc aux expressions françaises et les valeurs seront leurs traductions. Étant donné que nous possédons trois dossiers de langue (
fr_FR,
en_US,
de_DE), nous devons créer trois fichiers
.po différents. Attaquons tout de suite notre premier fichier :
en_US.
Code : Autre1
2
3
4
5
| msgid "Bienvenue !"
msgstr "Welcome !"
msgid "Au revoir !"
msgstr "Goodbye !" |
Analysons ce petit code : tout d'abord, nous voyons le mot
msgid
.
msgid
permet de définir une clé. Celle-ci est écrite entre guillemets. Dans la seconde ligne, nous pouvons voir un autre mot :
msgstr
.
msgstr
permet de définir une valeur. Celle-ci est également donnée entre guillemets.
Notez qu'il n'y a pas de ";" à la fin des lignes.

Ce code permet donc d'associer la valeur "Welcome !" à la clé "Bienvenue !". Ainsi, il suffira d'écrire "Bienvenue !" dans notre script et "Welcome !" sera automatiquement affiché. Ce n'est peut-être pas très parlant pour le moment mais ne vous inquiétez pas, vous comprendrez très vite.
Enregistrez ce fichier dans votre dossier
en_US/LC_MESSAGES/ et nommez-le
traductions.po.
En pratique, les expressions à traduire seront beaucoup plus longues (parfois de très longs textes). Pour faciliter la lecture et l'écriture de ces fichiers il est possible "d'étaler" les
msgid
et
msgstr
sur plusieurs lignes. En voici un exemple :
Code : Autre1
2
3
4
5
6
| msgid ""
"Ceci est un très long message"
" qui tient sur plusieurs lignes"
msgstr ""
"This is a long text written"
" on several lines" |
Comme vous pouvez le voir, on met deux guillemets vides après
msgid
et
msgstr
pour annoncer des sauts de lignes.
Répétons maintenant cette manipulation pour les dossier
fr_FR et
de_DE :
de_DE/LC_MESSAGES/traductions.po
Code : Autre1
2
3
4
5
| msgid "Bienvenue !"
msgstr "Wilkommen !"
msgid "Au revoir !"
msgstr "Auf Wiedersehen !" |
fr_FR/LC_MESSAGES/traductions.po
Code : Autre1
2
3
4
5
| msgid "Bienvenue !"
msgstr "Bienvenue !"
msgid "Au revoir !"
msgstr "Au revoir !" |
Donnez bien le même nom à vos fichiers de langues ! Ici, tous nos fichiers s'appellent
traductions.po.

Compilation
Maintenant que nous avons écrit nos fichiers de langue (
.po), nous allons devoir les compiler (
.mo). Pour cela, nous allons utiliser la commande
msgfmt
dans la console.
Elle s'utilise de cette façon :
Code : Console | msgfmt -o le_fichier_de_sortie.mo le_fichier_dentree.po |
Pour compiler notre fichier d'anglais, nous ferons donc :
Code : Console | msgfmt -o /dossier_racine/locale/en_US/LC_MESSAGES/traductions.mo /dossier_racine/locale/en_US/LC_MESSAGES/traductions.po |
Appuyez sur
ENTREE pour valider la commande. Si tout se passe bien, un fichier
.mo apparaît dans votre dossier
en_US/LC_MESSAGES/ à côté du
.po. C'est ce fichier dont nous nous servirons avec GetText.
Je vous laisse le soin de compiler les deux autres fichiers (
fr_FR,
de_DE). Pensez bien à donner leur
chemin complet !
Voilà qui est fait pour nos fichiers de traduction. Ils sont fin prêts à l'utilisation ! Dernière partie mais pas des moindres : le code PHP.
Maintenant que nous avons fini de préparer le terrain, nous allons pouvoir commencer à coder.
Pour afficher une traduction, il suffit de faire
echo gettext("La clé")
ou
echo _("La clé")
(c'est un alias). En faisant ceci, PHP ira chercher le fichier de traduction que nous aurons spécifié plus tôt dans le code et affichera la valeur (
msgstr
) correspondant à la clé entre guillemets (
msgid
).
Notre code sera très simple.
Nous créerons une page contenant 3 petits liens : français, anglais et allemand. En fonction du bouton sur lequel l'utilisateur aura cliqué, nous afficherons un message de bienvenue et nous lui dirons au revoir dans la langue souhaitée.
PHP fournit des fonctions permettant d'utiliser GetText. Voici celles que nous utiliserons :
Nous nous servirons également des fonctions
putenv()
et
setlocale()
qui permettent respectivement de modifier la valeur d'une
variable d'environnement et de changer les informations de localisation.
Je ne vais pas vous faire languir plus longtemps, voici le code entièrement commenté :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | <?php
if (!empty($_GET['lang'])) { // Si l'utilisateur a choisi une langue
switch ($_GET['lang']) { // En fonction de la langue, on crée une variable $langage qui contient le code
case 'fr':
$langage = 'fr_FR';
break;
case 'en':
$langage = 'en_US';
break;
case 'de':
$langage = 'de_DE';
break;
default:
$langage = 'fr_FR';
break;
}
putenv("LANG=$langage"); // On modifie la variable d'environnement
setlocale(LC_ALL, $langage); // On modifie les informations de localisation en fonction de la langue
$nomDesFichiersDeLangue = 'traductions'; // Le nom de nos fichiers .mo
bindtextdomain($nomDesFichiersDeLangue, "./locale"); // On indique le chemin vers les fichiers .mo
textdomain($nomDesFichiersDeLangue); // Le nom du domaine par défaut
/* On affiche les phrases traduites */
echo gettext('Bienvenue !');
echo '<br >';
echo _('Aurevoir !');
echo '<br /><br />';
}
/* On affiche les liens des différents langages */
echo '<a href="index.php?lang=fr">français</a><br />';
echo '<a href="index.php?lang=en">english</a><br />';
echo '<a href="index.php?lang=de">deutsch</a><br />';
?>
|
Ici, nous affichons trois liens correspondants à divers langages. Chacun d'eux envoie par l'URL une variable
$_GET['lang']
qui contient soit
fr
soit
en
soit
de
. Le script vérifie si cette variable existe (donc si l'utilisateur a choisi une langue) et si c'est le cas, en fonction de son contenu, il crée une variable
$langage
ayant pour valeur le code langage correspondant (
en
->
en_US,
fr
->
fr_FR,
de
->
de_DE). Les fonctions
putenv()
et
setlocale()
sont ensuite appelées avec comme attribut le contenu de
$variable
. Cela permet en gros de dire à PHP que l'utilisateur utilise telle langue. Puis nous indiquons le nom et l'emplacement de nos fichiers de traduction au moyen des fonctions
bindtextdomain()
et
textdomain()
. Enfin, nous affichons les phrases traduites avec
gettext()
qui prend en argument la clé du fichier de langue (
.mo) correspondant à la valeur traduite que l'on souhaite afficher. En fait, on dit à PHP le fichier qu'il doit aller chercher et la phrase qu'il doit trouver dans ce fichier.
Si vous testez ce code - et à condition que vous avez correctement suivi le tutoriel jusqu'ici - vous devriez voir que le texte est traduit en fonction du lien choisi.
C'est peut-être un peu flou pour le moment mais ne vous en faites pas, ça viendra avec la pratique.
Améliorons ce code
Le script que je vous ai donné était un exemple pour vous expliquer le fonctionnement de GetText. Il reste donc très basique et inutilisable de cette façon sur un vrai site web. Je ne suis pas là pour vous apprendre à coder mais voici quelques suggestions pour perfectionner votre système de traduction.
- Utilisez un cookie pour retenir la langue de l'utilisateur. Au prochain chargement, essayez de récupérer ce cookie pour afficher le site directement dans le langage préféré de l'utilisateur.
- Utilisez la superglobale $_SERVER["HTTP_ACCEPT_LANGUAGE"]
pour obtenir directement la langue favorite de l'utilisateur.
Pour le deuxième point, vous aurez besoin de traiter la valeur de
$_SERVER["HTTP_ACCEPT_LANGUAGE"]
. Voici une fonction trouvée sur le tutoriel original qui prend en argument la superglobale et qui renvoie un tableau contenant les langues préférées de l'utilisateur par ordre de préférence. Cette fonction retournant seulement les deux premières lettres (
en
,
fr
,
de
,
es
,
it
...), pensez à récupérer le code par la suite (
en_US,
fr_FR...).

Je ne m'attarderai pas sur ce code car ce n'est pas le but de mon tutoriel.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | <?php
function get_pref_language_array($str_http_languages)
{
$langs = explode(',',$str_http_languages);
$qcandidat = 0;
$nblang = count($langs);
for ($i=0; $i<$nblang; $i++)
{
for ($j=0; $j<count($langs); $j++) {
$lang = trim($langs[$j]);
if (!strstr($lang, ';') && $qcandidat != 1) {
$candidat = $lang;
$qcandidat = 1;
$indicecandidat = $j;
}
else {
$q = ereg_replace('.*;q=(.*)', '\\1', $lang);
if ($q > $qcandidat) {
$candidat = ereg_replace('(.*);.*', '\\1', $lang); ;
$qcandidat = $q;
$indicecandidat = $j;
}
}
}
$resultat[$i] = $candidat;
$qcandidat=0;
unset($langs[$indicecandidat]);
$langs = array_values($langs);
}
return $resultat;
}
?>
|
N'oubliez pas de toujours laisser le choix de la langue à l'utilisateur : avec cette fonction, un Français résidant aux USA ne pourra pas afficher votre site en français. Pensez donc à placer un lien ou un bouton vers les différentes langues.
Nous voilà arrivés à la fin de ce tutoriel. Comme vous l'avez sans doute constaté, GetText est une librairie puissante mais assez difficile à mettre en place. Cependant elle est préférable pour les sites affichant beaucoup de texte. Et personnellement, je trouve que cette façon de coder est "plus propre" que l'utilisation de centaines de variables ou de constantes qui viendront alourdir votre site.
Je tiens à préciser que je n'ai pas pu aborder TOUT ce qu'il y a à savoir sur GetText mais cela devrait être suffisant pour concocter un site multilingue correct. Si vous souhaitez approfondir vos connaissances sur le sujet, je vous invite à consulter les liens ci-dessous.
Pour tout problème ou suggestion, n'hésitez pas à poster un commentaire ou à demander de l'aide sur le forum.
Quelques liens utiles
Informations sur le tutoriel
Retour en haut
Créé : Le 07/11/2008 à 19:03:42
Modifié : Le 16/06/2009 à 12:20:43
Avancement : 100%
Licence : Copie non autorisée
32 commentaires