| 1 |
==================== |
|---|
| 2 |
Internationalisation |
|---|
| 3 |
==================== |
|---|
| 4 |
|
|---|
| 5 |
Django supporte pleinement l'internationalisation des textes aussi |
|---|
| 6 |
bien dans le code que dans les templates. Voici comment cela |
|---|
| 7 |
fonctionne : |
|---|
| 8 |
|
|---|
| 9 |
Aperçu |
|---|
| 10 |
====== |
|---|
| 11 |
|
|---|
| 12 |
Le but de l'internationalisation d'une application est de permettre à |
|---|
| 13 |
une application web de proposer son contenu et ses fonctionnalités |
|---|
| 14 |
dans de multiples langages. |
|---|
| 15 |
|
|---|
| 16 |
En tant que développeur Django vous pouvez atteindre ce but en |
|---|
| 17 |
ajoutant quelques appels de fonctions à votre code Python et à vos |
|---|
| 18 |
templates. Ces appels de fonctions sont appelés **"texte à traduire" |
|---|
| 19 |
(translation strings)**. Elles indiquent à Django : "Ce texte devrait |
|---|
| 20 |
être traduit dans la langue de l'utilisateur, si une traduction pour |
|---|
| 21 |
ce texte est disponible dans cette langue". |
|---|
| 22 |
|
|---|
| 23 |
Django se charge d'utiliser ces appels pour traduire à la volée les |
|---|
| 24 |
applications selon les préférences de l'utilisateur. |
|---|
| 25 |
|
|---|
| 26 |
Essentiellement Django fait 2 choses : |
|---|
| 27 |
|
|---|
| 28 |
* Il laisse aux développeurs et aux auteurs de templates le soin |
|---|
| 29 |
d'indiquer quelles parties de leurs applications devraient être |
|---|
| 30 |
traduites. |
|---|
| 31 |
* Il utilise les appels "texte à traduire" pour traduire les |
|---|
| 32 |
applications web pour les utilisateurs selon leurs préférences de langue. |
|---|
| 33 |
|
|---|
| 34 |
Comment internationaliser votre application en 3 étapes : |
|---|
| 35 |
--------------------------------------------------------- |
|---|
| 36 |
|
|---|
| 37 |
1. Inclure des appels "texte à traduire" dans votre code Python et vos |
|---|
| 38 |
templates. |
|---|
| 39 |
2. Obtenir les traductions pour ces textes, dans toutes les |
|---|
| 40 |
langues que vous souhaitez supporter. |
|---|
| 41 |
3. Activer le middleware locale dans votre fichier paramÚtre |
|---|
| 42 |
Django. |
|---|
| 43 |
|
|---|
| 44 |
.. admonition:: DerriÚre les fourneaux |
|---|
| 45 |
|
|---|
| 46 |
La machinerie Django de traduction utilise le module standard |
|---|
| 47 |
``gettext`` qui est livré avec Python. |
|---|
| 48 |
|
|---|
| 49 |
Si vous n'avez pas besoin de l'internationalisation |
|---|
| 50 |
=================================================== |
|---|
| 51 |
|
|---|
| 52 |
Les fonctions d'internationalisation de Django sont activées |
|---|
| 53 |
par défaut, cela signifie une surcharge dans certaines parties du |
|---|
| 54 |
framework. Si vous n'utilisez pas l'internationalisation, vous devriez |
|---|
| 55 |
prendre 2 secondes pour mettre ``USE_I18N = False`` dans votre fichier |
|---|
| 56 |
paramÚtre. Si ``USE_I18N`` est positionné à ``False``, Django peut |
|---|
| 57 |
alors procéder à quelques optimisations telles que ne pas charger la |
|---|
| 58 |
machinerie relative à l'internationalisation. |
|---|
| 59 |
|
|---|
| 60 |
Voir la `documentation pour USE_I18N`_. |
|---|
| 61 |
|
|---|
| 62 |
.. _documentation pour USE_I18N: http://www.djangoproject.com/documentation/settings/#use-i18n |
|---|
| 63 |
|
|---|
| 64 |
Comment spécifier les appels "texte à traduire" |
|---|
| 65 |
=============================================== |
|---|
| 66 |
|
|---|
| 67 |
Les appels "texte à traduire" signifient "Ce texte devrait être |
|---|
| 68 |
traduit". Ces appels peuvent apparaître dans votre code Python et vos |
|---|
| 69 |
templates. Il est de votre responsabilité de marquer les textes à |
|---|
| 70 |
traduire; le systÚme ne peut traduire que les textes dont il a |
|---|
| 71 |
connaissance. |
|---|
| 72 |
|
|---|
| 73 |
Dans le code Python |
|---|
| 74 |
------------------- |
|---|
| 75 |
|
|---|
| 76 |
Traduction standard |
|---|
| 77 |
~~~~~~~~~~~~~~~~~~~ |
|---|
| 78 |
|
|---|
| 79 |
Indiquez un texte à traduire en utilisant la fonction ``_()``. (Oui, |
|---|
| 80 |
le nom de la fonction est bien le caractÚre "souligné".) Cette |
|---|
| 81 |
fonction est disponible globalement dans n'importe quel module Python; |
|---|
| 82 |
vous n'avez pas besoin de l'importer. |
|---|
| 83 |
|
|---|
| 84 |
Dans cet exemple, le texte ``"Bienvenue sur mon site."`` est marqué |
|---|
| 85 |
comme un texte à traduire:: |
|---|
| 86 |
|
|---|
| 87 |
def my_view(request): |
|---|
| 88 |
output = _("Bienvenue sur mon site.") |
|---|
| 89 |
return HttpResponse(output) |
|---|
| 90 |
|
|---|
| 91 |
La fonction ``django.utils.translation.gettext()`` est identique à |
|---|
| 92 |
``_()``. |
|---|
| 93 |
Cet exemple est identique au précédent:: |
|---|
| 94 |
|
|---|
| 95 |
from django.utils.translation import gettext |
|---|
| 96 |
def my_view(request): |
|---|
| 97 |
output = gettext("Bienvenue sur mon site.") |
|---|
| 98 |
return HttpResponse(output) |
|---|
| 99 |
|
|---|
| 100 |
La traduction fonctionne avec des valeurs calculées. Cet exemple est |
|---|
| 101 |
identique aux 2 précédents:: |
|---|
| 102 |
|
|---|
| 103 |
def my_view(request): |
|---|
| 104 |
words = ['Bienvenue', 'sur', 'mon', 'site.'] |
|---|
| 105 |
output = _(' '.join(words)) |
|---|
| 106 |
return HttpResponse(output) |
|---|
| 107 |
|
|---|
| 108 |
La traduction fonctionne avec des variables. à nouveau voilà un |
|---|
| 109 |
exemple identique:: |
|---|
| 110 |
|
|---|
| 111 |
def my_view(request): |
|---|
| 112 |
sentence = 'Bienvenue sur mon site.' |
|---|
| 113 |
output = _(sentence) |
|---|
| 114 |
return HttpResponse(output) |
|---|
| 115 |
|
|---|
| 116 |
(Le problÚme d'utiliser des variables ou des valeurs calculées, comme |
|---|
| 117 |
dans les 2 précédents exemples, est que l'utilitaire Django de |
|---|
| 118 |
détection des textes à traduire, ``make-messages.py``, ne sera pas |
|---|
| 119 |
capable de trouver ces textes. Plus sur ``make-messages`` plus tard.) |
|---|
| 120 |
|
|---|
| 121 |
Les textes que vous passez à ``_()`` ou à ``gettext()`` peuvent |
|---|
| 122 |
contenir des marqueurs de formatage indiqués avec la même syntaxe |
|---|
| 123 |
standard que celle qu'utilise Python pour les marqueurs nommés. |
|---|
| 124 |
|
|---|
| 125 |
Exemple:: |
|---|
| 126 |
|
|---|
| 127 |
def my_view(request, n): |
|---|
| 128 |
output = _('%(name)s est mon nom.') % {'name': n} |
|---|
| 129 |
return HttpResponse(output) |
|---|
| 130 |
|
|---|
| 131 |
Cette technique permet le réordonnancement des marqueurs de formatage |
|---|
| 132 |
dans les traductions. Par exemple, une traduction anglaise pourrait |
|---|
| 133 |
être ``"Adrian is my name."``; tandis qu'une traduction espagnole |
|---|
| 134 |
pourrait être ``"Me llamo Adrian."`` -- avec le marqueur de formatage |
|---|
| 135 |
(le nom) placé aprÚs le texte traduit au lieu d'avant. |
|---|
| 136 |
|
|---|
| 137 |
Pour cette raison, vous devriez utiliser de préférence l'interpolation par les noms |
|---|
| 138 |
(e.g., ``%(name)s``) plutÃŽt que l'interpolation par position (e.g., |
|---|
| 139 |
``%s`` ou ``%d``). Si vous utilisez l'interpolation par position, la |
|---|
| 140 |
traduction sera incapable de réordonnancer les marqueurs de formatage. |
|---|
| 141 |
|
|---|
| 142 |
Marquage de textes sans traduction |
|---|
| 143 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 144 |
|
|---|
| 145 |
Utilisez la fonction ``django.utils.translation.gettext_noop()`` pour |
|---|
| 146 |
marquer un texte comme un texte à traduire mais sans le traduire. Le |
|---|
| 147 |
texte est traduit plus tard à partir d'une variable. |
|---|
| 148 |
|
|---|
| 149 |
Utilisez cette fonctionnalité si vous avez des chaînes constantes qui |
|---|
| 150 |
doivent être stockées dans le langage d'origine car elles sont |
|---|
| 151 |
échangées entre différents systÚmes ou utilisateurs -- telles que les |
|---|
| 152 |
chaînes dans une base de données -- mais qui doivent être traduites le |
|---|
| 153 |
plus tard possible, par exemple lorsque la chaîne est présentée à |
|---|
| 154 |
l'utilisateur. |
|---|
| 155 |
|
|---|
| 156 |
Traduction "paresseuse" |
|---|
| 157 |
~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 158 |
|
|---|
| 159 |
Utilisez la fonction ``django.utils.translation.gettext_lazy()`` pour |
|---|
| 160 |
traduire des textes de maniÚre *"paresseuse"* -- lorsque la valeur est |
|---|
| 161 |
accédée plutÎt que lorsque la fonction ``gettext_lazy()`` est appelée. |
|---|
| 162 |
|
|---|
| 163 |
Par exemple, pour traduire le paramÚtre ``help_text`` d'un modÚle, |
|---|
| 164 |
faites ceci:: |
|---|
| 165 |
|
|---|
| 166 |
from django.utils.translation import gettext_lazy |
|---|
| 167 |
|
|---|
| 168 |
class MyThing(models.Model): |
|---|
| 169 |
name = models.CharField(help_text=gettext_lazy("Ceci est le texte d'aide")) |
|---|
| 170 |
|
|---|
| 171 |
Dans cet exemple, ``gettext_lazy()`` stocke une référence |
|---|
| 172 |
*"paresseuse"* -- pas la traduction actuelle. La traduction proprement |
|---|
| 173 |
dite sera effectuée lorsque le texte sera utilisé dans un contexte |
|---|
| 174 |
chaîne de caractÚres, comme par exemple dans le rendu d'un template de |
|---|
| 175 |
la partie administration de Django. |
|---|
| 176 |
|
|---|
| 177 |
Si vous n'aimez pas le nom verbeux ``gettext_lazy``, vous pouvez tout |
|---|
| 178 |
simplement créer un alias de nom ``_``, comme ceci:: |
|---|
| 179 |
|
|---|
| 180 |
from django.utils.translation import gettext_lazy as _ |
|---|
| 181 |
|
|---|
| 182 |
class MyThing(models.Model): |
|---|
| 183 |
name = models.CharField(help_text=_("Ceci est le texte d'aide")) |
|---|
| 184 |
|
|---|
| 185 |
Utilisez toujours la traduction *"paresseuse"* dans les `modÚles |
|---|
| 186 |
Django`_. Et c'est une bonne idée d'ajouter la traduction pour les |
|---|
| 187 |
noms de champs et de tables aussi. Ceci signifie de positionner |
|---|
| 188 |
explicitement les options ``verbose_name`` et ``verbose_name_plural`` |
|---|
| 189 |
dans la classe ``Meta``, comme:: |
|---|
| 190 |
|
|---|
| 191 |
from django.utils.translation import gettext_lazy as _ |
|---|
| 192 |
|
|---|
| 193 |
class MyThing(models.Model): |
|---|
| 194 |
name = models.CharField(_('name'), help_text=_("Ceci est le texte d'aide")) |
|---|
| 195 |
class Meta: |
|---|
| 196 |
verbose_name = _('my thing') |
|---|
| 197 |
verbose_name_plural = _('mythings') |
|---|
| 198 |
|
|---|
| 199 |
.. _modÚles Django: http://www.djangoproject.com/documentation/model_api |
|---|
| 200 |
|
|---|
| 201 |
Pluriel |
|---|
| 202 |
~~~~~~~ |
|---|
| 203 |
|
|---|
| 204 |
Utilisez la fonction ``django.utils.translation.ngettext()`` pour |
|---|
| 205 |
indiquer le pluriel des textes. Exemple:: |
|---|
| 206 |
|
|---|
| 207 |
from django.utils.translation import ngettext |
|---|
| 208 |
def hello_world(request, count): |
|---|
| 209 |
page = ngettext("Il y'a %(count)d objet", "Il y'a %(count)d objets", count) % { |
|---|
| 210 |
'count': count, |
|---|
| 211 |
} |
|---|
| 212 |
return HttpResponse(page) |
|---|
| 213 |
|
|---|
| 214 |
``ngettext`` prend 3 arguments: le texte à traduire au singulier, le |
|---|
| 215 |
texte à traduire au pluriel et le nombre d'objets (lequel est passé |
|---|
| 216 |
aux traductions comme la variable ``count``). |
|---|
| 217 |
|
|---|
| 218 |
Dans les templates |
|---|
| 219 |
------------------ |
|---|
| 220 |
|
|---|
| 221 |
La traduction dans les `templates Django`_ utilise 2 tags avec une |
|---|
| 222 |
syntaxe légÚrement différente que celle utilisée dans le code Python. |
|---|
| 223 |
Pour donner à votre template accÚs à ces tags, indiquez ``{% load i18n |
|---|
| 224 |
%}`` vers le début de votre template. |
|---|
| 225 |
|
|---|
| 226 |
Le tag ``{% trans %}`` traduit une chaîne constante ou le contenu |
|---|
| 227 |
d'une variable:: |
|---|
| 228 |
|
|---|
| 229 |
<title>{% trans "Ceci est un titre" %}</title> |
|---|
| 230 |
|
|---|
| 231 |
Si vous voulez uniquement marquer une valeur à traduire, mais la |
|---|
| 232 |
traduire plus tard à partir d'une variable, utilisez l'option |
|---|
| 233 |
``noop``:: |
|---|
| 234 |
|
|---|
| 235 |
<title>{% trans "valeur" noop %}</title> |
|---|
| 236 |
|
|---|
| 237 |
Il n'est pas possible d'utiliser des variables de template dans le tag |
|---|
| 238 |
``{% trans %}`` -- seules les chaînes constantes, entre apostrophes ou |
|---|
| 239 |
guillemets, sont autorisées. Si votre traduction requiert des |
|---|
| 240 |
variables, utilisez le tag ``{% blocktrans %}``. Exemple:: |
|---|
| 241 |
|
|---|
| 242 |
{% blocktrans %}Ceci aura une {{ valeur }} à l'intérieur.{% endblocktrans %} |
|---|
| 243 |
|
|---|
| 244 |
Pour traduire une expression template -- par exemple qui utilise un |
|---|
| 245 |
filtre de template -- vous devez mettre en correspondance l'expression |
|---|
| 246 |
avec une variable locale pour pouvoir l'utiliser dans le bloc de |
|---|
| 247 |
traduction:: |
|---|
| 248 |
|
|---|
| 249 |
{% blocktrans with value|filter as myvar %} |
|---|
| 250 |
Ceci aura {{ myvar }} à l'intérieur. |
|---|
| 251 |
{% endblocktrans %} |
|---|
| 252 |
|
|---|
| 253 |
Si vous avez besoin de mettre en correspondance plus d'une expression |
|---|
| 254 |
à l'intérieur d'un tag ``blocktrans``, séparez les avec ``and``:: |
|---|
| 255 |
|
|---|
| 256 |
{% blocktrans with book|title as book_t and author|title as author_t %} |
|---|
| 257 |
Le livre {{ book_t }} de l'auteur {{ author_t }} |
|---|
| 258 |
{% endblocktrans %} |
|---|
| 259 |
|
|---|
| 260 |
Pour mettre au pluriel, indiquez le singulier et le pluriel avec le |
|---|
| 261 |
tag ``{% plural %}``, qui apparaît entre ``{% blocktrans %}`` |
|---|
| 262 |
et ``{% endblocktrans %}``. Exemple:: |
|---|
| 263 |
|
|---|
| 264 |
{% blocktrans count list|count as counter %} |
|---|
| 265 |
Il y'a seulement un objet {{ name }} |
|---|
| 266 |
{% plural %} |
|---|
| 267 |
Il y'a {{ counter }} objets {{ name }}. |
|---|
| 268 |
{% endblocktrans %} |
|---|
| 269 |
|
|---|
| 270 |
DerriÚre le rideau, toutes les traductions en ligne ou de bloc |
|---|
| 271 |
utilisent le bon appel ``gettext`` / ``ngettext``. |
|---|
| 272 |
|
|---|
| 273 |
Chaque ``RequestContext`` a accÚs à 3 variables spécifiques au |
|---|
| 274 |
mécanisme de traduction: |
|---|
| 275 |
|
|---|
| 276 |
* ``LANGUAGES`` est une liste de tuples dans lesquels le premier |
|---|
| 277 |
élément est le code du langage et le second le nom du langage |
|---|
| 278 |
(dans cette langue). |
|---|
| 279 |
* ``LANGUAGE_CODE`` est une chaîne représentant le langage préféré |
|---|
| 280 |
de l'utilisateur courant. Exemple: ``en-us``. (cf "Comment les |
|---|
| 281 |
préférences de langue sont détectées", ci-dessous) |
|---|
| 282 |
* ``LANGUAGE_BIDI`` est la direction du langage courant. Si True, |
|---|
| 283 |
il s'agit d'un langage qui se lit de droite à gauche, e.g: |
|---|
| 284 |
Hébreu, Arabe. Si False c'est un langage qui se lit de gauche à |
|---|
| 285 |
droite, e.g: Anglais, Français, Allemand etc. |
|---|
| 286 |
|
|---|
| 287 |
Si vous n'utilisez pas l'extension ``RequestContext``, vous pouvez |
|---|
| 288 |
obtenir ces valeurs avec ces 3 tags:: |
|---|
| 289 |
|
|---|
| 290 |
{% get_current_language as LANGUAGE_CODE %} |
|---|
| 291 |
{% get_available_languages as LANGUAGES %} |
|---|
| 292 |
{% get_current_language_bidi as LANGUAGE_BIDI %} |
|---|
| 293 |
|
|---|
| 294 |
Ces tags ne sont disponibles qu'aprÚs avoir appelé ``{% load i18n %}``. |
|---|
| 295 |
|
|---|
| 296 |
Les appels texte à traduire sont également disponibles à l'intérieur |
|---|
| 297 |
de tous les tags qui acceptent des chaînes constantes. Dans |
|---|
| 298 |
ces cas, utilisez la syntaxe ``_()`` pour indiquer un texte à |
|---|
| 299 |
traduire. Exemple:: |
|---|
| 300 |
|
|---|
| 301 |
{% some_special_tag _("Page non trouvée") value|yesno:_("oui,non") %} |
|---|
| 302 |
|
|---|
| 303 |
Dans cette hypothÚse, aussi bien le tag que le filtre recevrons la |
|---|
| 304 |
chaîne aprÚs traduction, ils n'auront alors pas à s'en préoccuper. |
|---|
| 305 |
|
|---|
| 306 |
.. _Templates Django: http://www.djangoproject.com/documentation/templates_python/ |
|---|
| 307 |
|
|---|
| 308 |
Comment créer des fichiers de langues |
|---|
| 309 |
===================================== |
|---|
| 310 |
|
|---|
| 311 |
Une fois que vous avez marqué vos textes pour une future traduction, |
|---|
| 312 |
vous devez écrire (ou obtenir) les traductions proprement dites. |
|---|
| 313 |
Voici comment cela fonctionne : |
|---|
| 314 |
|
|---|
| 315 |
Fichiers messages |
|---|
| 316 |
----------------- |
|---|
| 317 |
|
|---|
| 318 |
La premiÚre opération est de créer un **fichier message** pour un |
|---|
| 319 |
nouveau langage. Un fichier message est un fichier texte, |
|---|
| 320 |
représentant une langue, qui contient toutes les chaînes de traduction |
|---|
| 321 |
disponibles et leur traduction dans cette langue. Les fichiers |
|---|
| 322 |
messages ont une extension en ``.po``. |
|---|
| 323 |
|
|---|
| 324 |
Django est fourni avec un utilitaire, ``bin/make-messages.py``, qui |
|---|
| 325 |
automatise la création et la mise à jour de ces fichiers. |
|---|
| 326 |
|
|---|
| 327 |
Pour créer ou mettre à jour un fichier message, lancer cette |
|---|
| 328 |
commande:: |
|---|
| 329 |
|
|---|
| 330 |
bin/make-messages.py -l de |
|---|
| 331 |
|
|---|
| 332 |
...où ``de`` est le code du langage pour le fichier message que vous |
|---|
| 333 |
voulez créer. Le code du langage, dans ce cas, est dans le format |
|---|
| 334 |
locale. Par exemple, il s'agit de ``pt_BR`` pour le brésilien et |
|---|
| 335 |
``de_AT`` pour l'allemand autrichien. |
|---|
| 336 |
|
|---|
| 337 |
La commande devrait être lancée à partir d'un de ces 3 endroits: |
|---|
| 338 |
|
|---|
| 339 |
* Le répertoire racine ``django`` (pas un répertoire d'extraction |
|---|
| 340 |
Subversion, mais celui qui est indiqué dans la variable |
|---|
| 341 |
d'environnement ``$PYTHONPATH`` ou est situé quelque part dans |
|---|
| 342 |
ce chemin. |
|---|
| 343 |
* Le répertoire racine de votre projet Django. |
|---|
| 344 |
* Le répertoire racine de votre application Django. |
|---|
| 345 |
|
|---|
| 346 |
Le script parcourt l'ensemble de l'arborescence Django et extrait |
|---|
| 347 |
toutes les chaînes marquées comme à traduire. Il créé (ou met à jour) |
|---|
| 348 |
un fichier message dans le répertoire ``conf/locale``. Dans l'exemple |
|---|
| 349 |
``de``, le fichier sera ``conf/locale/de/LC_MESSAGES/django.po``. |
|---|
| 350 |
|
|---|
| 351 |
Si lancée à partir de la racine de votre projet ou application Django |
|---|
| 352 |
, il fera la même chose, mais la localisation du |
|---|
| 353 |
répertoire de traduction sera dans ce cas ``locale/LANG/LC_MESSAGES`` |
|---|
| 354 |
(notez l'absence du préfixe ``conf``). |
|---|
| 355 |
|
|---|
| 356 |
.. admonition:: gettext non disponible ? |
|---|
| 357 |
|
|---|
| 358 |
Si vous n'avez pas l'utilitaire ``gettext`` installé, |
|---|
| 359 |
``make-messages.py`` créera des fichiers vides. Si c'est le |
|---|
| 360 |
cas, soit vous installez l'utilitaire ``gettext`` soit vous |
|---|
| 361 |
copiez le fichier message anglais |
|---|
| 362 |
(``conf/locale/en/LC_MESSAGES/django.po``) et vous l'utilisez |
|---|
| 363 |
comme point de départ; il s'agit uniquement d'un fichier de |
|---|
| 364 |
traduction vide. |
|---|
| 365 |
|
|---|
| 366 |
Le format des fichiers ``.po`` est simple. Chaque fichier ``.po`` |
|---|
| 367 |
contient quelques meta-données, telles que l'information de contact du |
|---|
| 368 |
traducteur, mais l'essentiel du fichier est une liste de **messages** |
|---|
| 369 |
-- simple mise en correspondance entre les chaînes à traduire et la |
|---|
| 370 |
traduction pour le langage donné. |
|---|
| 371 |
|
|---|
| 372 |
Par exemple, si votre application Django contient une chaîne à |
|---|
| 373 |
traduire pour le texte ``"Bienvenue sur mon site."``, comme ceci:: |
|---|
| 374 |
|
|---|
| 375 |
_("Bienvenue sur mon site.") |
|---|
| 376 |
|
|---|
| 377 |
... ``make-messages.py`` aura alors créé un fichier ``.po`` contenant |
|---|
| 378 |
l'extrait suivant -- un message:: |
|---|
| 379 |
|
|---|
| 380 |
#: chemin/vers/python/module.py:23 |
|---|
| 381 |
msgid "Bienvenue sur mon site." |
|---|
| 382 |
msgstr "" |
|---|
| 383 |
|
|---|
| 384 |
Une petite explication: |
|---|
| 385 |
|
|---|
| 386 |
* ``msgid`` est la chaîne à traduire, qui apparaît dans le |
|---|
| 387 |
source. Ne la modifiez pas. |
|---|
| 388 |
* ``msgstr`` est la partie où vous indiquez la traduction. |
|---|
| 389 |
Elle est initialement vide, il est de votre ressort de la |
|---|
| 390 |
modifiez. Soyez sûr de bien conserver les guillemets |
|---|
| 391 |
autour de votre traduction. |
|---|
| 392 |
* à titre de facilité, chaque message comporte le nom du |
|---|
| 393 |
fichier et le numéro de ligne à partir duquel la chaîne à |
|---|
| 394 |
traduire a été récupérée. |
|---|
| 395 |
|
|---|
| 396 |
Les longs messages sont un cas particulier. D'abord, la 1Úre chaîne |
|---|
| 397 |
qui suit ``msgstr`` (ou ``msgid``) est une chaîne vide. Puis le |
|---|
| 398 |
contenu lui même sera écrit sur les lignes suivantes une chaîne par |
|---|
| 399 |
ligne. Ces chaînes sont directement concaténées. N'oubliez pas de |
|---|
| 400 |
mettre des espaces en fin de ligne dans ces chaînes; sinon elles |
|---|
| 401 |
seront assemblées ensemble sans espace ! |
|---|
| 402 |
|
|---|
| 403 |
.. admonition:: Occupez vous de l'encodage de vos caractÚres |
|---|
| 404 |
|
|---|
| 405 |
Quand vous créez un fichier ``.po`` avec votre éditeur de |
|---|
| 406 |
textes favori modifiez avant toute chose la ligne d'encodage |
|---|
| 407 |
des caractÚres (cherchez le mot ``"CHARSET"``) et modifiez le |
|---|
| 408 |
pour qu'il corresponde au jeu de caractÚres que vous utilisez |
|---|
| 409 |
pour éditer le contenu du fichier. Généralement, utf-8 devrait |
|---|
| 410 |
fonctionner pour la plupart des langages, mais ``gettext`` |
|---|
| 411 |
devrait accepter n'importe quel jeu que vous lui indiquez. |
|---|
| 412 |
|
|---|
| 413 |
Pour analyser à nouveau l'ensemble des codes source et templates |
|---|
| 414 |
pour de nouvelles chaînes à traduire et mettre à jour l'ensemble des |
|---|
| 415 |
fichiers message pour *l'ensemble* des langues, lancez cette |
|---|
| 416 |
commande:: |
|---|
| 417 |
|
|---|
| 418 |
make-messages.py -a |
|---|
| 419 |
|
|---|
| 420 |
Compilation des fichiers messages |
|---|
| 421 |
--------------------------------- |
|---|
| 422 |
|
|---|
| 423 |
AprÚs avoir créé votre fichier message -- et à chaque fois que vous le |
|---|
| 424 |
modifiez -- vous devez le recompiler dans une forme plus efficace pour |
|---|
| 425 |
``gettext``. Utilisez pour ce faire l'utilitaire |
|---|
| 426 |
``bin/compile-messages.py``. |
|---|
| 427 |
|
|---|
| 428 |
Cette commande parcourt tous les fichiers ``.po`` et créée des fichiers |
|---|
| 429 |
``.mo``, qui sont des fichiers binaires optimisés pour ``gettext``. à |
|---|
| 430 |
partir du même répertoire que celui utilisé pour lancer |
|---|
| 431 |
``make-messages.py``, lancez ``compile-messages.py`` comme ceci:: |
|---|
| 432 |
|
|---|
| 433 |
bin/compile-messages.py |
|---|
| 434 |
|
|---|
| 435 |
C'est tout. Vos traductions sont prêtes à être utilisées. |
|---|
| 436 |
|
|---|
| 437 |
.. admonition:: Note pour les traducteurs |
|---|
| 438 |
|
|---|
| 439 |
Si vous avez créé une traduction dans une langue que Django ne |
|---|
| 440 |
supporte pas encore, merci de nous le faire savoir ! Voir |
|---|
| 441 |
`Soumettre et maintenir une traduction`_ pour la démarche à |
|---|
| 442 |
suivre. |
|---|
| 443 |
|
|---|
| 444 |
.. _Soumettre et maintenir une traduction: http://www.djangoproject.com/documentation/contributing/ |
|---|
| 445 |
|
|---|
| 446 |
Comment Django identifie les préférences de langue |
|---|
| 447 |
================================================== |
|---|
| 448 |
|
|---|
| 449 |
Une fois que vos traductions sont prêtes -- ou, si vous désirez utiliser |
|---|
| 450 |
uniquement les traductions livrées avec Django -- vous devez activer |
|---|
| 451 |
la traduction pour votre application. |
|---|
| 452 |
|
|---|
| 453 |
DerriÚre les rideaux, Django a un mécanisme trÚs souple pour décider |
|---|
| 454 |
quelle langue devrait être utilisée -- propre à l'installation, |
|---|
| 455 |
pour un utilisateur en particulier, ou pour les 2. |
|---|
| 456 |
|
|---|
| 457 |
Pour indiquer des préférences de langue propres à une installation de |
|---|
| 458 |
Django, positionnez ``LANGUAGE_CODE`` dans votre `fichier de |
|---|
| 459 |
paramÚtres Django`_. Django utilise cette langue comme la langue par |
|---|
| 460 |
défaut -- si aucune autre n'est trouvée. |
|---|
| 461 |
|
|---|
| 462 |
Si tout ce que vous voulez est de lancer Django sous votre langue |
|---|
| 463 |
natale, et un fichier de langue est disponible pour celle-ci, tout ce |
|---|
| 464 |
que vous avez à faire est de positionner ``LANGUAGE_CODE``. |
|---|
| 465 |
|
|---|
| 466 |
Si vous voulez que chaque utilisateur puisse indiquer quelle langue il |
|---|
| 467 |
ou elle préfÚre, utilisez ``LocaleMiddleware``. ``LocaleMiddleware`` |
|---|
| 468 |
active la sélection de langue en fonction de données fournies dans la |
|---|
| 469 |
requête. Il adapte le contenu pour chaque utilisateur. |
|---|
| 470 |
|
|---|
| 471 |
Pour utiliser ``LocaleMiddleware``, ajoutez |
|---|
| 472 |
``'django.middleware.locale.LocaleMiddleware'`` à votre paramÚtre |
|---|
| 473 |
``MIDDLEWARE_CLASSES``. Parce que l'ordre des middleware compte, vous |
|---|
| 474 |
devriez suivre ces conseils: |
|---|
| 475 |
|
|---|
| 476 |
* Soyez sûr que c'est un des premiers middlewares installé. |
|---|
| 477 |
* Il devrait suivre ``SessionMiddleware``, parce que |
|---|
| 478 |
``LocaleMiddleware`` utilise les données de session. |
|---|
| 479 |
* Si vous utilisez ``CacheMiddleware``, mettez |
|---|
| 480 |
``LocaleMiddleware`` aprÚs lui. |
|---|
| 481 |
|
|---|
| 482 |
Par exemple, votre ``MIDDLEWARE_CLASSES`` pourrait ressembler à ceci:: |
|---|
| 483 |
|
|---|
| 484 |
MIDDLEWARE_CLASSES = ( |
|---|
| 485 |
'django.contrib.sessions.middleware.SessionMiddleware', |
|---|
| 486 |
'django.middleware.locale.LocaleMiddleware', |
|---|
| 487 |
'django.middleware.common.CommonMiddleware', |
|---|
| 488 |
) |
|---|
| 489 |
|
|---|
| 490 |
(Pour plus d'informations sur les middleware, voir la `documentation |
|---|
| 491 |
sur les middleware`_.) |
|---|
| 492 |
|
|---|
| 493 |
``LocaleMiddleware`` tente de déterminer les préférences de langue de |
|---|
| 494 |
l'utilisateur en suivant cet algorithme: |
|---|
| 495 |
|
|---|
| 496 |
* PremiÚrement, il recherche une clé ``django_language`` dans |
|---|
| 497 |
la `session`_ courante de l'utilisateur. |
|---|
| 498 |
* Si cela échoue, il recherche un cookie de nom |
|---|
| 499 |
``django_language``. |
|---|
| 500 |
* Si cela échoue, il recherche un en-tête HTTP |
|---|
| 501 |
``Accept-Language``. Cet en-tête est envoyé par votre |
|---|
| 502 |
navigateur et indique au serveur quel(s) langue(s) vous |
|---|
| 503 |
préférez, par ordre de priorité décroissante. Django essai |
|---|
| 504 |
chaque langue dans cet en-tête jusqu'à ce qu'il trouve une |
|---|
| 505 |
traduction existante. |
|---|
| 506 |
* Si tout cela échoue, il utilise la préférence globale |
|---|
| 507 |
``LANGUAGE_CODE``. |
|---|
| 508 |
|
|---|
| 509 |
Notes: |
|---|
| 510 |
|
|---|
| 511 |
* à chacun de ces endroits, la préférence de langue est |
|---|
| 512 |
attendue dans le format standard, comme une chaîne de |
|---|
| 513 |
caractÚres. Par exemple, le brésilien est indiqué comme |
|---|
| 514 |
``pt-br``. |
|---|
| 515 |
* Si une langue de base est disponible mais le dialecte |
|---|
| 516 |
spécifié ne l'est pas, Django utilise la langue de base. Par |
|---|
| 517 |
exemple, si un utilisateur indique ``de-at`` (allemand |
|---|
| 518 |
autrichien) mais Django ne dispose que de ``de``, Django |
|---|
| 519 |
utilisera ``de``. |
|---|
| 520 |
* Seules les langues listées dans le `paramÚtre LANGUAGES`_ |
|---|
| 521 |
peuvent être sélectionnées. Si vous voulez restreindre la |
|---|
| 522 |
sélection de langue à un sous-ensemble des langues fournies |
|---|
| 523 |
(parce que par exemple votre application ne fournie pas |
|---|
| 524 |
toutes ces langues); positionnez ``LANGUAGES`` Ã une liste |
|---|
| 525 |
appropriées. Par exemple:: |
|---|
| 526 |
|
|---|
| 527 |
LANGUAGES = ( |
|---|
| 528 |
('de', _('German')), |
|---|
| 529 |
('en', _('English')), |
|---|
| 530 |
) |
|---|
| 531 |
|
|---|
| 532 |
Cet exemple limite les langues disponibles pour une |
|---|
| 533 |
sélection automatique à l'allemand et l'anglais (et tous les |
|---|
| 534 |
dialectes correspondants, comme de-ch ou en-us). |
|---|
| 535 |
|
|---|
| 536 |
.. _paramÚtre LANGUAGES: http://www.djangoproject.com/documentation/settings/#languages |
|---|
| 537 |
|
|---|
| 538 |
* Si vous définissez le paramÚtre ``LANGUAGES``, comme |
|---|
| 539 |
expliqué dans le point ci-dessus, il est possible d'indiquer |
|---|
| 540 |
les langues comme des chaînes à traduire -- mais utilisez |
|---|
| 541 |
une fonction ``gettext()`` "vide", pas celle dans le module |
|---|
| 542 |
``django.utils.translation``. Vous ne devriez *jamais* |
|---|
| 543 |
importer ``django.utils.translation`` Ã partir de votre |
|---|
| 544 |
fichier paramÚtres, parce que ce module dépend lui même des |
|---|
| 545 |
paramÚtres, ce qui créerait un import circulaire. |
|---|
| 546 |
|
|---|
| 547 |
La solution est d'utiliser une fonction ``gettext`` vide. |
|---|
| 548 |
Ci-dessous un exemple de fichier paramÚtre:: |
|---|
| 549 |
|
|---|
| 550 |
gettext = lambda s: s |
|---|
| 551 |
|
|---|
| 552 |
LANGUAGES = ( |
|---|
| 553 |
('de', gettext('German')), |
|---|
| 554 |
('en', gettext('English')), |
|---|
| 555 |
) |
|---|
| 556 |
|
|---|
| 557 |
Avec ce code, ``make-messages.py`` trouvera et marquera toujours |
|---|
| 558 |
ces chaînes comme à traduire, mais la traduction ne se fera pas |
|---|
| 559 |
lors de l'exécution du code -- aussi vous devrez vous rappeler |
|---|
| 560 |
d'englober les chaînes à traduire avec la *véritable* fonction |
|---|
| 561 |
``gettext()`` dans tout code qui utilise ``LANGUAGES`` lors de |
|---|
| 562 |
l'exécution du code. |
|---|
| 563 |
|
|---|
| 564 |
* Le ``LocaleMiddleware`` peut sélectionner uniquement les langues |
|---|
| 565 |
pour lesquelles Django fournit une traduction de base. Si vous |
|---|
| 566 |
désirez fournir une traduction pour votre application qui n'est |
|---|
| 567 |
pas déjà dans l'ensemble des traductions incluses dans les |
|---|
| 568 |
sources Django, vous devrez au moins fournir une traduction de |
|---|
| 569 |
base pour cette langue. Par exemple, Django utilise des messages |
|---|
| 570 |
ID technique pour traduire les formats de date et de temps -- |
|---|
| 571 |
aussi vous aurez au minimum besoin d'avoir ces traductions pour |
|---|
| 572 |
que le systÚme fonctionne correctement. |
|---|
| 573 |
|
|---|
| 574 |
Un bon point de départ est de copier le fichier ``.po`` anglais |
|---|
| 575 |
et de traduire au minimum les messages techniques -- peut être |
|---|
| 576 |
également les messages de validation. |
|---|
| 577 |
|
|---|
| 578 |
Les messages ID techniques sont facilement reconnaissables; ils |
|---|
| 579 |
sont tous en majuscules. Vous ne traduisez pas les messages ID |
|---|
| 580 |
comme les autres messages, vous fournissez la variante locale |
|---|
| 581 |
correcte correspondante à la valeur anglaise. Par exemple, avec |
|---|
| 582 |
``DATETIME_FORMAT`` (ou ``DATE_FORMAT`` ou ``TIME_FORMAT``), |
|---|
| 583 |
cela serait la chaîne de format que vous voulez utiliser pour |
|---|
| 584 |
cette langue. Le format est identique aux chaînes de format |
|---|
| 585 |
utilisées avec le tag de template ``now``. |
|---|
| 586 |
|
|---|
| 587 |
Une fois que ``LocaleMiddleware`` a déterminé la préférence de |
|---|
| 588 |
l'utilisateur, il rend cette préférence disponible dans |
|---|
| 589 |
``request.LANGUAGE_CODE`` pour chaque `objet requête`_. Vous êtes |
|---|
| 590 |
libre d'utiliser cette valeur dans votre code. Voici un simple |
|---|
| 591 |
exemple:: |
|---|
| 592 |
|
|---|
| 593 |
def hello_world(request, count): |
|---|
| 594 |
if request.LANGUAGE_CODE == 'de-at': |
|---|
| 595 |
return HttpResponse("Vous préférez lire l'allemand autrichien") |
|---|
| 596 |
else: |
|---|
| 597 |
return HttpResponse("Vous préférez lire une autre langue") |
|---|
| 598 |
|
|---|
| 599 |
Notez qu'avec une traduction statique (sans middleware), la langue est |
|---|
| 600 |
dans ``settings.LANGUAGE_CODE``, tandis qu'avec une traduction |
|---|
| 601 |
dynamique (middleware) elle est dans ``request.LANGUAGE_CODE``. |
|---|
| 602 |
|
|---|
| 603 |
.. _fichier de paramÚtres Django: http://www.djangoproject.com/documentation/settings/ |
|---|
| 604 |
.. _documentation sur les middleware: http://www.djangoproject.com/documentation/middleware/ |
|---|
| 605 |
.. _session: http://www.djangoproject.com/documentation/sessions/ |
|---|
| 606 |
.. _objet requête: https://www.djangoproject.com/documentation/request_response/#httprequest-objects |
|---|
| 607 |
|
|---|
| 608 |
La vue de redirection ``set_language`` |
|---|
| 609 |
====================================== |
|---|
| 610 |
|
|---|
| 611 |
à titre de facilité, Django est fournie avec une vue, |
|---|
| 612 |
``django.views.i18n.set_language``, qui positionne les préférences de |
|---|
| 613 |
langue de l'utilisateur puis redirige vers la page précédente. |
|---|
| 614 |
|
|---|
| 615 |
Activez cette vue en ajoutant la ligne suivante dans votre URLconf:: |
|---|
| 616 |
|
|---|
| 617 |
(r'^i18n/', include('django.conf.urls.i18n')), |
|---|
| 618 |
|
|---|
| 619 |
(Notez que cet exemple rend la vue disponible à l'url |
|---|
| 620 |
``/i18n/setlang/``.) |
|---|
| 621 |
|
|---|
| 622 |
La vue attend a être appelée via la méthode ``GET``, avec un |
|---|
| 623 |
paramÚtre ``language`` positionné dans la chaîne de requête. Si le |
|---|
| 624 |
support des sessions est activé, la vue sauvegarde le choix de la |
|---|
| 625 |
langue dans la session de l'utilisateur. Autrement, elle sauvegarde le |
|---|
| 626 |
choix de la langue dans un cookie ``django_language``. |
|---|
| 627 |
|
|---|
| 628 |
AprÚs avoir positionné le langage choisi, Django redirige |
|---|
| 629 |
l'utilisateur, selon l'algorithme suivant: |
|---|
| 630 |
|
|---|
| 631 |
* Django recherche un paramÚtre de nom ``next`` dans la chaîne de |
|---|
| 632 |
requête. |
|---|
| 633 |
* Si celui-ci n'existe pas, ou est vide, Django essai l'URL de |
|---|
| 634 |
l'en-tête ``Referer``. |
|---|
| 635 |
* Si celui-ci est vide -- disons, si le navigateur de |
|---|
| 636 |
l'utilisateur supprime cet en-tête -- alors l'utilisateur sera |
|---|
| 637 |
redirigé vers ``/`` (la racine du site) à défaut. |
|---|
| 638 |
|
|---|
| 639 |
Ci-dessous un exemple HTML dans un template:: |
|---|
| 640 |
|
|---|
| 641 |
<form action="/i18n/setlang/" method="get"> |
|---|
| 642 |
<input name="next" type="hidden" value="/next/page/" /> |
|---|
| 643 |
<select name="language"> |
|---|
| 644 |
{% for lang in LANGUAGES %} |
|---|
| 645 |
<option value="{{ lang.0 }}">{{ lang.1 }}</option> |
|---|
| 646 |
{% endfor %} |
|---|
| 647 |
</select> |
|---|
| 648 |
<input type="submit" value="Go" /> |
|---|
| 649 |
</form> |
|---|
| 650 |
|
|---|
| 651 |
Utilisation des traductions dans vos propres projets |
|---|
| 652 |
==================================================== |
|---|
| 653 |
|
|---|
| 654 |
Django recherche des traductions en suivant cet algorithme: |
|---|
| 655 |
|
|---|
| 656 |
* PremiÚrement, il recherche un répertoire ``locale`` dans le |
|---|
| 657 |
répertoire de l'application de la vue qui est appelée. Si il |
|---|
| 658 |
trouve une traduction pour la langue sélectionnée, elle |
|---|
| 659 |
sera installée. |
|---|
| 660 |
* Ensuite, il recherche un répertoire ``locale`` dans le |
|---|
| 661 |
répertoire du projet Django. Si il trouve une traduction, elle |
|---|
| 662 |
sera installée. |
|---|
| 663 |
* Finalement, il vérifie les traductions de base dans |
|---|
| 664 |
``django/conf/locale``. |
|---|
| 665 |
|
|---|
| 666 |
De cette maniÚre vous pouvez écrire des applications qui inclut leur |
|---|
| 667 |
propre traductions, et vous pouvez redéfinir les traductions de base |
|---|
| 668 |
dans votre répertoire projet Django. Ou, vous pouvez élaborer un grand |
|---|
| 669 |
projet à partir de plusieurs applications et mettre l'ensemble des |
|---|
| 670 |
traductions dans un grand et unique fichier messages du projet. Le |
|---|
| 671 |
choix vous appartient. |
|---|
| 672 |
|
|---|
| 673 |
.. note:: |
|---|
| 674 |
|
|---|
| 675 |
Si vous utilisez la configuration manuelle de votre fichier |
|---|
| 676 |
paramÚtres, tel que définit dans la `documentation sur le fichier |
|---|
| 677 |
paramÚtres`_, le répertoire ``locale`` de votre répertoire projet |
|---|
| 678 |
ne sera pas examiné, puisque Django perd la possibilité de |
|---|
| 679 |
travailler à partir de l'emplacement de votre projet. (Django |
|---|
| 680 |
normalement utilise l'emplacement du fichier paramÚtres pour |
|---|
| 681 |
déterminer ceci, et un fichier paramÚtres n'existe pas si vous |
|---|
| 682 |
configurez manuellement vos paramÚtres). |
|---|
| 683 |
|
|---|
| 684 |
.. _documentation sur le fichier paramÚtres: http://www.djangoproject.com/documentation/settings/#using-settings-without-the-django-settings-module-environment-variable |
|---|
| 685 |
|
|---|
| 686 |
L'ensemble des répertoires de fichiers messages ont une structure identique : |
|---|
| 687 |
|
|---|
| 688 |
* ``$APPPATH/locale/<langue>/LC_MESSAGES/django.(po|mo)`` |
|---|
| 689 |
* ``$PROJECTPATH/locale/<langue>/LC_MESSAGES/django.(po|mo)`` |
|---|
| 690 |
* Tous les chemins indiqués dans la variable ``LOCALE_PATHS`` de votre |
|---|
| 691 |
fichier paramÚtres sont parcourus dans cet ordre à la recherche |
|---|
| 692 |
de fichiers ``<langue>/LC_MESSAGES/django.(po|mo)`` |
|---|
| 693 |
* ``$PYTHONPATH/django/conf/locale/<langue>/LC_MESSAGES/django.(po|mo)`` |
|---|
| 694 |
|
|---|
| 695 |
Pour créer des fichiers de traduction, vous utilisez le même |
|---|
| 696 |
utilitaire que pour la traduction des fichiers de traduction Django, Ã |
|---|
| 697 |
savoir ``make-messages.py``. Vous devez seulement vous assurer que |
|---|
| 698 |
vous êtes au bon endroit -- soit dans le répertoire parent de ``conf/locale`` |
|---|
| 699 |
(si dans la hiérarchie source Django) soit dans le répertoire parent de |
|---|
| 700 |
``locale/``(si il s'agit de traductions de projets ou d'applications). |
|---|
| 701 |
Et vous utilisez le même utilitaire ``compile-messages.py`` pour |
|---|
| 702 |
générer les fichiers binaires ``django.mo`` utilisés par ``gettext``. |
|---|
| 703 |
|
|---|
| 704 |
Les fichiers de traduction des applications sont plus difficiles à |
|---|
| 705 |
détecter -- ils ont besoin de ``LocaleMiddleware``. Si vous n'utilisez |
|---|
| 706 |
pas le middleware, seuls les fichiers de traduction de Django et des |
|---|
| 707 |
projets seront traités. |
|---|
| 708 |
|
|---|
| 709 |
Pour finir, vous devriez réfléchir à la structure de vos fichiers de |
|---|
| 710 |
traduction. Si vos applications doivent être distribuées à d'autres |
|---|
| 711 |
utilisateurs pour être utilisées dans d'autres projets, vous pourriez |
|---|
| 712 |
vouloir faire des traductions spécifiques à vos applications. Mais |
|---|
| 713 |
faire des traductions spécifiques à des applications ou à des projets |
|---|
| 714 |
pourrait générer des problÚmes avec ``make-messages``: |
|---|
| 715 |
``make-messages`` parcourt l'ensemble des répertoires situés sous le |
|---|
| 716 |
chemin courant et en conséquence pourrait mettre des messages ID dans |
|---|
| 717 |
le fichier de traduction du projet qui sont déjà dans les fichiers de |
|---|
| 718 |
traduction des applications. |
|---|
| 719 |
|
|---|
| 720 |
Le meilleur moyen de s'en sortir est de mettre les applications qui ne |
|---|
| 721 |
font pas partie du projet (et donc qui comportent leur propre |
|---|
| 722 |
traductions) en dehors de la hiérarchie du projet. De cette maniÚre, |
|---|
| 723 |
``make-messages`` lancé à partir du répertoire du projet ne traduira |
|---|
| 724 |
que les chaînes qui sont spécifiques à votre projet et non les chaînes |
|---|
| 725 |
distribuées indépendamment. |
|---|
| 726 |
|
|---|
| 727 |
Traductions et Javascript |
|---|
| 728 |
========================= |
|---|
| 729 |
|
|---|
| 730 |
Ajouter des traductions à Javascript pose certains problÚmes : |
|---|
| 731 |
|
|---|
| 732 |
* Le code Javascript n'a pas accÚs à la librairie ``gettext``. |
|---|
| 733 |
|
|---|
| 734 |
* Le code Javascript n'a pas accÚs aux fichiers .po ou .mo; ils |
|---|
| 735 |
doivent être envoyés par le serveur. |
|---|
| 736 |
|
|---|
| 737 |
* Le catalogue des chaînes traduites pour Javascript devrait être |
|---|
| 738 |
aussi léger que possible. |
|---|
| 739 |
|
|---|
| 740 |
Django fournit une solution intégrée pour ces problÚmes : il transmet |
|---|
| 741 |
les traductions à Javascript de telle maniÚre que vous puissiez |
|---|
| 742 |
appeler ``gettext``, etc... Ã partir de votre code Javascript. |
|---|
| 743 |
|
|---|
| 744 |
La vue ``javascript_catalog`` |
|---|
| 745 |
----------------------------- |
|---|
| 746 |
|
|---|
| 747 |
La solution principale à ces problÚmes est la vue |
|---|
| 748 |
``javascript_catalog`` qui renvoie une librairie en Javascript qui |
|---|
| 749 |
reproduit l'interface ``gettext`` accompagnée d'un tableau des chaînes |
|---|
| 750 |
traduites. Ces chaînes sont extraites de l'application, du projet ou |
|---|
| 751 |
de Django selon ce que vous indiquez dans soit le dictionnaire |
|---|
| 752 |
{{{info_dict}}} ou l'URL. |
|---|
| 753 |
|
|---|
| 754 |
Vous assemblez les choses comme suit:: |
|---|
| 755 |
|
|---|
| 756 |
js_info_dict = { |
|---|
| 757 |
'packages': ('votre.application.package'), |
|---|
| 758 |
} |
|---|
| 759 |
|
|---|
| 760 |
urlpatterns = patterns('', |
|---|
| 761 |
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), |
|---|
| 762 |
) |
|---|
| 763 |
|
|---|
| 764 |
Chaque chaîne dans ``packages`` devrait être exprimée dans la même |
|---|
| 765 |
syntaxe que Python utilise pour les packages (même format que les |
|---|
| 766 |
chaînes utilisées dans la variable ``INSTALLED-APPS``) et devrait |
|---|
| 767 |
faire référence à un package qui contient un répertoire ``locale``. Si |
|---|
| 768 |
vous indiquez plusieurs packages, tous les catalogues qu'ils |
|---|
| 769 |
contiennent sont fusionnés en un seul catalogue. Ceci peut être utile |
|---|
| 770 |
si votre code Javascript utilise des chaînes de plusieurs |
|---|
| 771 |
applications. |
|---|
| 772 |
|
|---|
| 773 |
Vous pouvez rendre la vue dynamique en mettant les packages dans les |
|---|
| 774 |
modÚles d'URL (URL pattern):: |
|---|
| 775 |
|
|---|
| 776 |
urlpatterns = patterns('', |
|---|
| 777 |
(r'^jsi18n/(?P<packages>\S+?)/$, 'django.views.i18n.javascript_catalog'), |
|---|
| 778 |
) |
|---|
| 779 |
|
|---|
| 780 |
Comme ceci vous indiquez les packages comme une liste de noms de |
|---|
| 781 |
packages délimités par le signe '+' dans l'URL. Cela peut être |
|---|
| 782 |
particuliÚrement utile si vos pages utilisent du code de différentes |
|---|
| 783 |
applications, que cela change souvent et que vous ne voulez pas |
|---|
| 784 |
rassembler le tout dans un unique catalogue. Ã titre de mesure de |
|---|
| 785 |
sécurité, ces valeurs ne peuvent qu'être soit ``django.conf``, soit |
|---|
| 786 |
n'importe quel package apparaissant dans la variable |
|---|
| 787 |
``INSTALLED_APPS``. |
|---|
| 788 |
|
|---|
| 789 |
Utilisation du catalogue de traductions avec Javascript |
|---|
| 790 |
------------------------------------------------------- |
|---|
| 791 |
|
|---|
| 792 |
Pour utiliser le catalogue, appelez le code Javascript généré |
|---|
| 793 |
dynamiquement comme suit:: |
|---|
| 794 |
|
|---|
| 795 |
<script type="text/javascript" src="/chemin/vers/jsi18n/"></script> |
|---|
| 796 |
|
|---|
| 797 |
C'est comme cela que l'interface d'administration de Django récupÚre |
|---|
| 798 |
le catalogue de traductions à partir du serveur. Lorsque le catalogue |
|---|
| 799 |
est chargé, votre code Javascript peut utiliser l'interface standard |
|---|
| 800 |
``gettext`` pour y accéder:: |
|---|
| 801 |
|
|---|
| 802 |
document.write(gettext('ceci est à traduire')); |
|---|
| 803 |
|
|---|
| 804 |
``ngettext`` et la fonction d'interpolation des chaînes sont même |
|---|
| 805 |
disponibles:: |
|---|
| 806 |
|
|---|
| 807 |
d = { |
|---|
| 808 |
count: 10 |
|---|
| 809 |
}; |
|---|
| 810 |
s = interpolate(ngettext("il y'a %(count)s objet", "il y'a ù%count)s objets", d.count), d); |
|---|
| 811 |
|
|---|
| 812 |
La fonction ``interpolate`` supporte aussi bien l'interpolation par |
|---|
| 813 |
position que l'interpolation nommée. Le code dessus aurait pu être |
|---|
| 814 |
écrit comme suit:: |
|---|
| 815 |
|
|---|
| 816 |
s = interpolate(ngettext("il y'a %s objet", "il y a %s objets", 11), [11]); |
|---|
| 817 |
|
|---|
| 818 |
La syntaxe pour l'interpolation est empruntée de Python. Vous ne |
|---|
| 819 |
devriez pas trop en demander cependant avec l'interpolation de |
|---|
| 820 |
chaînes: cela reste du Javascript aussi le code devra faire des |
|---|
| 821 |
substitutions répétées avec des expressions réguliÚres. Ce n'est pas |
|---|
| 822 |
aussi rapide que l'interpolation de chaînes avec Python aussi réservez |
|---|
| 823 |
les aux cas où vous en avez vraiment besoin (par exemple en |
|---|
| 824 |
conjonction avec ``ngettext`` pour générer des mises au pluriel |
|---|
| 825 |
correctes) |
|---|
| 826 |
|
|---|
| 827 |
Création des catalogues de traductions pour Javascript |
|---|
| 828 |
------------------------------------------------------ |
|---|
| 829 |
|
|---|
| 830 |
Vous créez et mettez à jour les catalogues de traductions de la même |
|---|
| 831 |
maniÚre que ceux de Django -- avec l'utilitaire |
|---|
| 832 |
{{{make-messages.py}}}. La seule différence est que vous devez |
|---|
| 833 |
fournir le paramÚtre ``-d djangojs``, comme ceci:: |
|---|
| 834 |
|
|---|
| 835 |
make-messages.py -d djangojs -l de |
|---|
| 836 |
|
|---|
| 837 |
Ceci créera ou mettra à jour le catalogue des traductions allemandes |
|---|
| 838 |
pour Javascript. AprÚs mise à jour des catalogues de traductions, |
|---|
| 839 |
lancer ``compile-messages.py`` de la même maniÚre que vous le faites |
|---|
| 840 |
pour les catalogues de traductions Django. |
|---|
| 841 |
|
|---|
| 842 |
Particularités de la traduction Django |
|---|
| 843 |
====================================== |
|---|
| 844 |
|
|---|
| 845 |
Si vous connaissez ``gettext`` vous pourriez remarquer ces |
|---|
| 846 |
particularités dans la maniÚre dont Django effectue les traductions: |
|---|
| 847 |
|
|---|
| 848 |
* La chaîne de domaine est ``django`` ou ``djangojs``. La chaîne |
|---|
| 849 |
de domaine est utilisée pour différencier entre différents |
|---|
| 850 |
programmes qui stockent leurs données dans un fichier des |
|---|
| 851 |
messages commun (généralement ``/usr/share/locale``). Le domaine |
|---|
| 852 |
``django`` est utilisé par Python et les chaînes de traduction |
|---|
| 853 |
des templates et est chargé dans les catalogues de traductions |
|---|
| 854 |
globaux. Le domaine ``djangojs`` est uniquement utilisé pour les |
|---|
| 855 |
catalogues de traductions Javascript pour être sûr qu'ils sont |
|---|
| 856 |
le plus lÚger possible. |
|---|
| 857 |
* Django utilise uniquement ``gettext`` et ``gettext_noop``. Parce |
|---|
| 858 |
que Django utilise toujours les chaînes ``DEFAULT_CHARSET`` de maniÚre |
|---|
| 859 |
interne. Il n'y a pas beaucoup matiÚre à utiliser ``ugettext`` |
|---|
| 860 |
car vous devrez toujours fournir utf-8 dans tous les cas. |
|---|
| 861 |
* Django n'utilise pas ``xgettext`` seul. Il utilise des |
|---|
| 862 |
enveloppes Python autour de ``xgettext`` et ``msgfmt``. |
|---|
| 863 |
Principalement pour convenance. |
|---|
| 864 |
|
|---|