Extraire les strings d'une application basée sur Hyla TPL ou sur PHP Lib
By Gregoire de Hemptinne on Tuesday, December 21 2010, 08:54 - Applications - Permalink
Une fois une application crée, une fois un thème réalisé, on est heureux de pouvoir en faire profiter tout le monde. Seulement voilà, tout le monde ne parle pas la même langue que nous. Donc si nous souhaitons distribuer notre thème à plus grande échelle il est évident qu'une internationalisation (i18n ou l10n) du thème sera nécessaire. Les développeurs d'applications web PHP connaissent bien ce problème et il est maintenant courant d'utiliser gettext pour gérer les différentes langues dans une application.


Ceci dit, une fois le thème crée, ça n'est pas toujours évident d'en extraire le texte pour créer un support gettext qui permet une traduction facile dans plusieurs langues. C'est donc en travaillant sur le Bilboplanet que je me suis confronté à cette difficulté. Mon but était de rendre l'application la plus générique possible : et donc traduisible en fonction des besoins. Extraire les strings de mon application à la main aurait été impossible ... d'autant plus que je modifie souvent mon code et il serait impensable de garder ma liste de traductions à jour. J'avais donc besoin d'un outil automatique.
J'ai donc mis en place un petit script d'extraction de strings automatique pour le moteur de templates Hyla TPL (qui est compatible avec PHP Lib) pour générer les fichiers .po dont j'avais besoin. Le code est disponible ici :
La fonction à appeler pour lancer la génération du fichier gettext est la fonction "extract_tpl(tpldir)" à laquelle vous devez passer en paramètre le chemin vers votre répertoire de thème. La fonction ira automatiquement chercher le fichier "index.tpl" et suivra les liens internes du type "include" pour que tous les fichiers inclus soient aussi traduits. Le résultat est un fichier .po que vous pouvez ensuite traduire à votre guise :
def extract_tpl(tpldir):
translate = Translation(tpldir)
if os.path.isfile(os.path.join(os.path.abspath(tpldir), 'index.tpl')):
translate.extract_from_tpl('', 'index.tpl')
else:
translate.extract_tpl()
potcontent = translate.gettext_code()
print potcontent
Pour ceux qui n'y connaissent rien en python mais qui souhaiteraient quand même tester ce script. Je vous invite à installer python et ipython chez vous. Puis dans le répertoire dans lequel se trouve le fichier python ci-dessus, faites :
greg@gsat:~/Desktop$ ls export_tpl.py
export_tpl.py
greg@gsat:~/Desktop$ ipython
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)
Type "copyright", "credits" or "license" for more information.
IPython 0.10 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: from export_tpl import *
In [2]: extract_tpl('/home/greg/Public/bilboplanet/themes/gil-galad/')



Comments
Si j'ai bien compris tu cherches à générer un fichier .pot de ton template.
Python possède un module (en standard) qui s'appelle gettext, de plus, il existe un module Python spécialisé dans ce que tu cherches à faire, il s'appelle Babel avec un utilitaire en ligne de commande, pybabel
Et sinon tu as normalement xgettext, qui fait la même chose que ton programme (et peut-être mieux)
Pourquoi ré-inventer la roue
C'est en aucun cas un reproche.
Hello,
Olivier, il n'a pas réinventer la route, il a juste fait un bout de code qui extrait les expressions à traduire d'un fichier gabarit possédant la syntaxe de Hyla Tpl, chose que gettext en standard n'est pas capable de faire...
C'est en quelque sorte un wrapper.
Merci The Climber de partager.
++
@Olivier : comme expliqué par Hugo ci-dessus, je ne ré-invente pas la roue. J'extrait simplement les chaines de caractères qui ne sont pas dans un format classique gérable par gettext.
Il s'agit donc bel et bien d'un script utile

J'ai pas mal cherché sur le web avant de me lancer (n'ayant justement pas envie de ré-inventer la roue)... ne trouvant rien, j'ai décidé de le faire moi-même
Pourtant en parcourant ton script, je vois que tu recherches les occurrences de
_(...). Cette fonction est généralement utilisée par gettext.Après je ne connais pas Hyla TPL.
Non, je fais une recherche sur {_XXX} et pas sur _(XXX)
Je te renvoie vers tes expressions régulières
Hum... quid de poedit ? Il ne peut pas faire ça en natif ? En lui indiquant les expressions régulières des balises de template ?
Remarque à la lecture de ton code :
si tu as un template inclus plusieurs fois tu vas le cité plusieurs fois. Il n'est pas préférable de généré la liste des fichiers de façon unique puis de les traiter.
ie index.tpl inclue A.tpl et B.tpl et A et B inclue C.tpl, Tu vas avoir un truc du genre pour chaque chaine de C
#: C.tpl:<ligne>
#: C.tpl:<ligne>
..... pour chaque inclusion 2 dans notre cas
msgid <chaine>
msgstr ""
Même si le doublons de commentaire ne pose pas de problème
C'est quand même dommage si xgetext prend pas en charge des expressions régulière en entrée...
Ton script ne prend pas en charge la mise à jour d'un ficher po. Tu va devoir re-coder le --join-existing de xgettext. Il n'est pas plus simple de faire une copie du répertoire de ton thème dans le répertoire temporaire du système, de remplacer {_string} par _(string) et de lancer xgettext dessus. Cela permet d'avoir toute la puissance et la flexibilité de xgettext à très faible coût de développement, maintenance, etc...