Nouveau ! Sans LLM dedans ! Je suis nécrophile amoureuse de Grégory Lemarchal
Utiliser gettext avec PHP
15/06/2007 - 10:01:01
Je cherchais tout récemment un moyen pratique et rapide de pouvoir utiliser les fonctions de la bibliothèque gettext avec PHP. Je me suis rendu compte après quelques recherches qu'il y avait peu d'information sur le sujet. Les rares didacticiels dénichés m'indiquaient qu'il y avait peu d'information sur le sujet. J'ai donc l'honneur de perpétuer cette honorable coutume en vous annonçant qu'il y a peu d'information sur le sujet.
Mais heureusement, il y en a une qui est assez claire et complète pour m'avoir permis de parvenir à mes fins après quelques tentatives. En revanche elle est en anglais, je vais donc me charger ici principalement de la traduire.
Gettext est une bibliothèque très utile lorsqu'on souhaite internationaliser une application et bien entendu, elle est utilisable avec PHP >= 4.
Petite digression, pour l'internationalisation, j'ai trouvé trois méthodes :
- Créer des fichiers de langage avec une liste de constantes. C'est la méthode utilisée par PHP-Nuke.
- Stocker toutes les chaînes dans une base de données, ce qui est bien sûr plus pratique pour les manipuler, mais forcément un peu plus long à implémenter. C'est la méthode utilisée par Drupal.
- Utiliser gettext, la méthode selon moi la plus pratique et la plus efficace, mais malheureusement, elle n'est pas applicable sur tous les hébergements. Hors Web, c'est la méthode utilisée par Pidgin.
Commençons donc par installer gettext.
sudo apt-get install gettext
Pour pouvoir traduire automatiquement une chaîne, il suffit d'utiliser la fonction gettext() ou son alias _() :
<?php
echo gettext('Hello World !'); // Ou bien echo _('Hello World !');
?>
Dans un premier temps, il convient donc d'utiliser la fonction gettext() pour toutes les chaînes à afficher, pour chaque echo() ou print() donc.
Votre application est, au niveau du code, presque prête. Il reste à générer les fichiers de traduction, portant l'extension .mo habituellement. Notez que ces fichiers sont spécifiques à la plate-forme utilisée. Si vous les créez sous Linux, il ne seront pas utilisables sur un serveur fonctionnant sous Windows. La génération se passe en plusieurs étapes.
En premier lieu, il faut extraire de l'application toutes les chaînes nécessitant une traduction. Si vous avez bien suivi, il s'agit de toutes celles utilisant la fonction gettext(). Cette étape nécessite l'usage du programme xgettext. On peut donc, pour en faciliter l'utilisation, créer un fichier contenant une liste de tous les fichiers de l'application où se trouvent les chaînes à traduire.
find <dossier de l'application> -name '*.php' > liste_fichiers.txt
Maintenant que nous avons la liste, il faut l'envoyer à xgettext pour qu'il parse les fichiers.
xgettext -f liste_fichiers.txt -o messages.pot
Cette commande créera un catalogue portant le nom de messages.pot contenant la liste des chaînes à traduire. Ensuite, à vous de faire la traduction. Pour cela, il existe plusieurs outils dédiés, dont Kbabel (Linux/KDE) ou Poedit (Linux/Windows/OS X). Dans ce didacticiel, nous utiliserons Poedit.
Lancez Poedit. Dans le menu Ficher, sélectionnez « Nouveau catalogue depuis un fichier POT », entrez les informations demandées puis choisissez le fichier messages.pot. L'interface rudimentaire est séparée en deux colonnes. Celle de gauche représente les chaînes originales, celle de droite les chaînes traduites. C'est celle-ci que vous devez remplir.
Imaginons que vous souhaitez réaliser une traduction de l'anglais vers le français, sauvegardez le fichier sous le nom de, par exemple, messages.po.
À la base de votre application, créez un dossier que vous pouvez appeler l10n, l'abbréviation de localization. Dans ce dossier, créez le dossier fr_FR.UTF8, et à l'intérieur de celui-ci, le dossier LC_MESSAGES.
Dans le même dossier que votre fichier messages.po, il se peut que Poedit crée directement le fichier messages.mo. Si ce n'est pas le cas, vous pouvez le créer vous-même à l'aide de la commande :
msgfmt -o messages.mo messages.po
Ce fichier messages.po doit être déplacé dans le dossier l10n/fr_FR.UTF8/LC_MESSAGES/.
Votre application est maintenant internationalisée, localisée, il reste à lui indiquer quels fichiers de traduction utiliser. Dans un fichier d'en-tête par exemple, ou avant toute traduction, ajoutez le code suivant :
<?php
$lang = 'fr_FR.UTF8';
$textdomain = 'messages';
setlocale(LC_ALL, $lang);
bindtextdomain($textdomain, 'l10n');
textdomain($textdomain);
?>
Pour une première approche basique, peu avancée, c'est tout ce qu'il y avait à faire. Vous pouvez utiliser votre application et constater que les chaînes originales ont été remplacées par celles que vous aviez indiquées à l'aide de Poedit.
Didacticiel très librement inspiré de Tutorial for the easy use of gettext for internationalization of PHP Apps.







10 jolis commentaires :
#1) 22/10/2007 - 23:57:53
Tres interressant ce sujet, bien expliqué. Il semble donc neccessaire d'avoir la main sur le serveur pour utiliser gettext.
Pourquoi cetains hebergeur l'on installé si elle n'est pas utilisable? Y a une astuce?
http://imu104.infomaniak.ch/extensions.php?ext=gettext&lang=french
#2) 22/11/2007 - 12:32:12
Bah c'est tout con. Suffit de faire le .mo sur ta machine, et de l'uploader sur ton serveur.
A condition evidemment de faire attention a faire le .mo sur le meme OS (et meme archi tres certainement) que celui de ton serveur.
#3) 03/01/2008 - 18:35:36
tu es sur aue tout fonctionne?? il semblerait que xgettext n'accepte pas le php.
moi j'ai cette erreur : xgettext: warning: file `/var/www/html/www.xxxxxxxxxx/test_page_dont_commit/pgeMain.php' extension `php' is unknown; will try C
Peux tu me dire comment tu as pu passer cette etape stp??
#4) 03/01/2008 - 18:52:29
xgettext --language=PHP
#5) 04/01/2008 - 12:28:49
Salut Mallory,
vu que ma version de xgettext est trop vieille et que je ne peux pas la mettre a jour (d raison de stabilite), j'ai donc fait fonctionner comme suit : xgettext -kgettext /var/www/...Page.php --language=C++ -o welcome.pot puisse qu'apperement cela fonctionne bien vu que PHP est proche de C++.
Mon probleme c'est que malgre les gettext dans la page.php, il ne mets aucun mot dans mon dico welcome.pot.
C'est pour cela que je souhaiterais savoir s'il fallait absoluement mettre tout le bordel
<?php
$lang = 'fr_FR.UTF8';
$textdomain = 'messages';
setlocale(LC_ALL, $lang);
bindtextdomain($textdomain, 'l10n');
textdomain($textdomain);
?>
dans la page avant d'appeler la commande xgettext ou alors s'il s agit d un autre probleme?
#6) 14/01/2008 - 22:11:40
Bonjour Johan,
Je ne peux pas t'aider en ce qui concerne la génération des dictionnaires.
En revanche «tout le bordel» n'est absolument pas nécessaire à la génération de ces derniers. Le bordel sert à indiquer à PHP/Gettext quels seront les fichiers de traduction à utiliser.
#7) 26/02/2008 - 14:38:52
Bonjour, et merci pour ce petit tutoriel bien utile. Je laisse juste ce message pour indiquer à qui aurait le même problème que moi qu'il m'a fallu ajouter
putenv("LANGUAGE=$lang" );
#8) 26/02/2008 - 14:58:53
Merci de la précision Paul.
On retrouve en effet cette ligne dans plusieurs autres didacticiels, mais je n'ai aucune information sur son but, sur le type d'environnement dans lequel elle s'avère nécessaire.
#9) 01/08/2008 - 17:31:25
MALLORY,
il semble que le
putenv("LANGUAGE=$lang" );
soit nécessaire pour une distribution Linux Debian.
Du reste, ce tuto est vraiment très bien fait.
Un autre tuto sympa ici ...
http://www.mandragor.org/tutoriels/gettext/0
#10) 02/08/2008 - 22:41:08
Merci pour les précisions