Internationalisation

date:2012-05-01 20:46
tags:django, python
category:Django
author:Rémy Hubscher

Coder en Anglais, déployer en Français

Le code Python a une syntaxe proche de l’anglais.

while, if, for, open, etc.

Par conséquent arriver avec du Français là dedans n’est pas une bonne idée.

De plus, comme vous utilisés des produits Open Source, vous avez un rôle à jouer pour déployer vous aussi vos programmes en Open Source ou participer à des projets existants que vous allez utiliser et sûrement patcher.

Il faut donc prendre l’habitude de coder en Anglais.

D’un autre côté, nos utilisateurs eux sont français et comme dans un premier temps notre projet n’a pas une visé internationale, on s’en fout un peu que tout s’affiche en Anglais.

Heureusement Django a prévu le coup.

Babel s’appelle gettext

gettext c’est une application qui a pour unique but de faire de la traduction de programmes open source. Quasiment tous les programmes Open Source l’utilise pour l’internationalisation de leur programme.

Django n’échappe pas à la règle car gettext fonctionne plutôt bien.

Intégrer gettext dans son code

Pour traduire des chaines de caractères

Aux endroits où l’on souhaite traduire, on va utiliser :

from django.utils.translation import ugettext as _
translated_string = _('This will be translated')

Dans les models, on utilise toujours ugettext_lazy qui permet de retarder la traduction de la chaîne au moment de l’affichage.

Si on traduit une phrase avec des valeurs issues de variables, il faut penser à nommer les variables pour que le traducteur s’y retrouve :

output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}

Si on souhaite gérer les accords en nombre, on utilise ungettext :

from django.utils.translation import ungettext

def hello_world(request, count):
    page = ungettext(
        'there is %(count)d object',
        'there are %(count)d objects',
    count) % {
        'count': count,
    }
    return HttpResponse(page)

Dans les templates

Dans les templates, on utilise un templatetag de la librairie i18n

{% load i18n %}
{% trans 'This will be translated' %}

Si l’on a des variables dans la chaine à traduire

{% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}

S’il s’agit du champ d’une variable ou que l’on souhaite faire passer la valeur dans un filter

{% blocktrans with amount=article.price %}
That will cost $ {{ amount }}.
{% endblocktrans %}

{% blocktrans with myvar=value|filter %}
This will have {{ myvar }} inside.
{% endblocktrans %}

Pour plus d’information : https://docs.djangoproject.com/en/dev/topics/i18n/translation/

Traduire son application

Pour l’utiliser c’est assez simple, on se rends dans le répertoire de son application, on créé un répertoire locale et on lance

$ cd tuto_django/todo/
$ mkdir locale
$ django-admin.py makemessage -l fr
processing language fr

Cela va nous créer le fichier : tuto_django/todo/locale/fr/LC_MESSAGES/django.po

On peut éditer ce fichier et entrer notre traduction

# Traduction de notre application de liste de tâches
# Copyright (C) 2012 Rémy HUBSCHER
# This file is distributed under the same license as the PACKAGE package.
# Rémy HUBSCHER <remy.hubscher@ionyse.com>, 2012
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Todos\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-01 20:54+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"

#: models.py:6
msgid "task"
msgstr "tâche"

#: models.py:7
msgid "Resolved?"
msgstr "Terminée ?"

#: templates/todo/tasks-list.html:6
msgid "Todo list"
msgstr "Liste de tâches"

#: templates/todo/tasks-list.html:14
msgid "Todos"
msgstr "À faire"

#: templates/todo/tasks-list.html:17
msgid "What needs to be done?"
msgstr "Que devez vous faire ?"

#: templates/todo/tasks-list.html:26
msgid "Mark all as complete"
msgstr "Toutes marquer comme terminées"

#: templates/todo/tasks-list.html:50
msgid "Clear completed"
msgstr "Éffacer les tâches terminées"

#: templates/todo/tasks-list.html:56
msgid "Double-click to edit a todo."
msgstr "Double cliquer pour éditer la tâche."

Compiler le fichier de traduction

Une fois ceci fait

$ django-admin.py compilemessages
processing file django.po in tuto_django/todo/locale/fr/LC_MESSAGES

Ensuite puisque votre settings définit le français comme étant la langue par défaut, après avoir relancé votre serveur, votre application est maintenant en Français.

../_images/todo-fr.png

Informations complémentaires

Pour rajouter une langue, vous refaites un makemessages -l de et vous avez un fichier prêt à être traduit en allemand que vous pouvez donner à votre traducteur.

Lorsqu’il y a des modifications, il suffit de relancer la commande makemessages -l fr pour mettre à jour le fichier po.

Les lignes précédés de #, fuzzy ne sont pas prises en compte lors de la compilation, il faut donc vérifier la traduction puis supprimer le #, fuzzy.

Conclusion

Sans rien faire de spécial, avec juste un peu de rigueur, vous avez maintenant une application en Français et en Anglais prette à l’emploi.