L'internationalisation et la traduction d'une application écrite en
Django.
25 avril 2010
Appuyez sur → pour avancer.
* pas le musicien mais le poney
Stéphane Raimbault
Licence Apache, version 2.0 sauf les photos en références.
Note : 18 caractères entre le « i » et le « n »
Note : 10 caractères entre le « l » et le « n »
#: lib/gai_strerror.c:75
msgid "Unknown error"
msgstr "Erreur inconnue"
#: lib/getopt.c:529 lib/getopt.c:545
#, c-format
msgid "%s: option '%s' is ambiguous\n"
msgstr "%s : l'option « %s » est ambiguë\n"
La chaîne de référence est usuellement la chaîne anglaise.
USE_I18N et USE_L10NTEMPLATE_CONTEXT_PROCESSORSMIDDLEWARE_CLASSES
django_language dans la sessionLANGUAGE_COOKIE_NAMEHTTP_ACCEPT_LANGUAGE dans la requêteUSE_I18N et USE_L10NTEMPLATE_CONTEXT_PROCESSORSMIDDLEWARE_CLASSES
ugettext_lazy permet de différer la traduction de la chaîne en argument
from django.utils.translation import ugettext_lazy
class Estranger(models.Model):
name = models.CharField(
help_text=ugettext_lazy('Nom de l'estranger du dehors'))
from django.utils.translation import ugettext_lazy as _
class Estranger(models.Model):
name = models.CharField(help_text=_('Nom de l'estranger du dehors'))
return u"%s" % ugettext_lazy("Ce gâteau est estouffe belle-mère")
ugettext est utilisée car la langue est connue
from django.utils.translation import ugettext as _
def my_view(request):
output = _("Adieu estranger.")
return HttpResponse(output)
from django.utils.translation import ugettext as _
def my_view(request):
sentence = u"Se manger 4 panisses à l'Estaque c'est marseillais 45°."
output = _(sentence)
return HttpResponse(output)
ugettext_noop
def my_view(request, m, d):
output = _('Today is %s, %d') % (m, d)
return HttpResponse(output)
#: hello/views.py:75 msgid "Today is %s, %d"Le traducteur ne dispose d'aucune information sur les arguments et ne peut pas changer l'ordre, la phrase « Today is November, 26 » doit être traduite par « Hoy es 26 de Noviembre » en espagnol. Heureusement, gettext vous avertira du problème.
def my_view(request, m, d):
output = _('Today is %(month)s, %(day)s.') % {'month': m, 'day': d}
return HttpResponse(output)
#: hello/views.py:75 msgid "Today is %(month)s, %(day)s"
Plural-Forms: nplurals=2; plural=(n > 1);
Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 &&
(n%100<10 ""|| n%100>=20) ? 1 : 2 msgid "Really delete this note?" msgid_plural "Really delete these %1% notes?" msgstr[0] "Ne pewno usunąć tę notatkę?" msgstr[1] "Ne pewno usunąć %1% notatki?" msgstr[2] "Ne pewno usunąć %1% notatek?"
if nb_bouteille == 1django.utils.translation.ungettext() arrive à la rescousse
from django.utils.translation import ungettext
def hello_world(request, count):
page = ungettext(
'there is %(count)d bottle of pastaga',
'there are %(count)d bottles of pastaga', count) % { 'count': count }
return HttpResponse(page)
{% load i18n %}{% trans "Home" %} {% trans name %}
{% blocktrans with language.team.get_description as team_name %}
You need to be authenticated and to be member of the {{ team_name }} team.
{% endblocktrans %}
Mon exemple est incorrect, attention aux retours à la ligne !
#, python-format
msgid "You need to be authenticated and to be member of the %(team_name)s team."
blocktrans
{% blocktrans count bottle_list|length as counter %}
There is {{ counter}} bottle.
{% plural %}
There are {{ counter }} bottles.
{% endblocktrans %}
js_info_dict = {
'domain': 'djangojs',
'packages': ('hello',),
}
urlpatterns = patterns('',
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
La documentation de Django ne précise pas quel est le domaine par défaut (djangojs.po)
#: ../data/GNOME_GnoteApplet.xml.h:2 ../src/actionmanager.cpp:208 #: ../src/tray.cpp:468 msgid "_Help" msgstr "Aid_e"
gettext insère un champ supplémentaire dans le fichier PO (msgctxt)formats.py
USE_THOUSAND_SEPARATOR)
locale./manage.py makemessages -l fr ./manage.py compilemessages
gettext permet de vérifier que le fichier est valide
msgfmt --statistics -c -v -o django.mo django.po

stephane.raimbault@makina-corpus.com