root/docs/trunk/i18n.txt

Revision 299, 35.8 kB (checked in by david, 3 years ago)

qui a traduit ça ?! qu'il se manifeste :-)

Line 
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
Note: See TracBrowser for help on using the browser.