Archives du mot-clé I18n

Inter­na­tio­na­li­ser une appli­ca­tion Mojo­li­cious

Faire une appli­ca­tion Mojo­li­cious, c’est bien, faire une appli­ca­tion Mojo­li­cious qui soit traduite dans plusieurs langages, c’est mieux !

Pour commen­cer, il faut instal­ler le plugin Mojo­li­cious::Plugin::I18N, qui va faire le gros du boulot.

On l’ac­tive simple­ment avec

$self->plugin('I18N');

dans le fichier prin­ci­pal de l’ap­pli­ca­tion (il y a des options possibles, listées sur la page CPAN du plugin).

Pour utili­ser les traduc­tions, on utilise le helper l :

# dans un fichier de template
<%=l 'truc' %>
# dans un controller
$c->l('truc');

Ensuite, on crée des fichiers de traduc­tion. J’ai long­temps fait comme indiqué sur la page du plugin, à savoir, par exemple pour le français, un fichier fr.pm qui contient la variable %Lexi­con qui elle-même contient les traduc­tions, dans un dossier I18N de l’ar­bo­res­cence de l’ap­pli­ca­tion (voir la page du plugin pour les détails). Ça marche, mais ce n’est pas vrai­ment très agréable à utili­ser. Il faut passer sur chaque fichier de traduc­tion pour rajou­ter une phrase, c’est un peu fasti­dieux.

Gettext est un système de traduc­tion bien connu qui a l’avan­tage d’avoir plein d’ou­tils pour l’uti­li­ser. On va donc plutôt utili­ser cela.

Pour pouvoir extraire auto­ma­tique­ment toutes les chaînes de traduc­tion, nous allons avoir besoin du module Perl Locale::Make­text::Extract qui four­nit le binaire xgettext.pl qui va servir à l’ex­trac­tion.

Pour que xgettext.pl réus­sisse à tout extraire correc­te­ment, une petite modi­fi­ca­tion de la syntaxe utili­sée précé­dem­ment dans les templates est néces­saire.

Au lieu de

<%=l 'truc' %>

on écrira désor­mais

<%= l('truc') %>

Comme je n’ai pas envie de parser tous mes fichiers, qui ne contiennent pas tous des chaînes à traduire, j’ai listé les fichiers perti­nents dans un fichier locales_files.txt.

Pour extraire mes chaînes :

xgettext.pl -f locales_files.txt

Cela donne un fichier messages.po. L’op­tion -o FILE permet de dire dans quel fichier mettre les chaînes à traduire. Si le fichier cible existe déjà, xgettext.pl le mettra à jour si besoin est.

Pour utili­ser faci­le­ment ce fichier de traduc­tion, nous allons le placer dans le réper­toire de traduc­tion du plugin Mojo­li­cious. Et le renom­mer pour lui donner le nom d’un langage. Pour mon projet Lstu, cela donne lib/Lstu/I18N/fr.po, en lieu et place du fichier lib/Lstu/I18N/fr.pm évoqué plus haut.

Pour dire au plugin Mojo­li­cious d’uti­li­ser direc­te­ment les fichiers .po, on va créer le fichier lib/Lstu/I18N.pm :

package Lstu::I18N;

use base 'Locale::Maketext';
use File::Basename qw/dirname/;
use Locale::Maketext::Lexicon {
    _auto => 1,
    _decode => 1,
    '*' => [Gettext => dirname(__FILE__) . '/I18N/*.po']
};

1;

Et c’est fini ! Il ne reste plus qu’à copier le fichier fr.po dans les langages voulus et à les traduire.

cp fr.po en.po
vi en.po

Dès qu’un nouveau fichier de langue est détecté par l’ap­pli­ca­tion (un petit restart de l’ap­pli­ca­tion est néces­saire), le langage sera proposé lorsqu’un visi­teur utili­sant ce langage dans les préfé­rences de son navi­ga­teur passera par là :-).

On peut utili­ser poedit pour modi­fier les fichiers .po, cela offre des faci­li­tés que ne propose pas vim. Et l’uti­li­sa­tion du format .po permet d’uti­li­ser – par exemple — la plate­forme Tran­si­fex pour coor­don­ner les efforts de traduc­tion. Je sais, ça pue, c’est pas libre, mais il faut dire ce qui est, c’est pratique. D’ailleurs, j’ai déposé les fichiers de traduc­tion de Lstu sur Tran­si­fex, si le cœur vous en dit :-)

J’ai trouvé cette nouvelle façon de traduire mes appli­ca­tions Mojo­li­cious via ce billet et celui-ci.

Me soutenir sur Tipeee Me soutenir sur Liberapay