Archives du mot-clé Mojolicious

Erco : Exabgp Routes Control­ler

Pour les besoins du réseau Lothaire (aka « mon boulot »), j’ai écrit un service web permet­tant de pilo­ter Exabgp (logi­ciel permet­tant de faire des annonces de routes en BGP. C’est du Soft­ware-Defi­ned Networ­king) afin de lui ajou­ter ou de lui reti­rer des routes de façon simple, afin de faire du RTBH (Remo­tely Trig­ge­red Black Hole).

Ce logi­ciel (libre, bien sûr, comment pour­rait-il en être autre­ment ?), s’ap­pelle Erco (Exabgp ROutes COntrol­ler). Le site de présen­ta­tion est https://erco.xyz, et une démo est dispo­nible sur https://erco.xyz/demo/.
Soyez indul­gents sur le temps de char­ge­ment du site, c’est hébergé chez moi, derrière de l’ADSL.

Le service expose une API REST, ce qui permet à Erco d’être piloté par des programmes.

Pour les besoins du service, j’ai écrit un programme pour expo­ser l’API d’Exabgp, et inci­dem­ment, j’ai écrit un client en ligne de commande pour cette API.

Les sources d’Erco sont sur https://git.frama­soft.org/luc/erco.

Pour les curieux de tech­nique, le logi­ciel est écrit en Perl avec le frame­work Mojo­li­cious (bien sûr, comment pour­rait-il en être autre­ment ? 1).

1 : c’est pas parce qu’on n’est pas vendredi qu’on n’a pas le droit de trol­ler un peu :-P

Me soutenir sur Tipeee Me soutenir sur Liberapay

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