~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to docs/topics/i18n.txt

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
.. _topics-i18n:
2
 
 
3
 
====================
4
 
Internationalization
5
 
====================
6
 
 
7
 
Django has full support for internationalization of text in code and templates.
8
 
Here's how it works.
9
 
 
10
 
Overview
11
 
========
12
 
 
13
 
The goal of internationalization is to allow a single Web application to offer
14
 
its content and functionality in multiple languages.
15
 
 
16
 
You, the Django developer, can accomplish this goal by adding a minimal amount
17
 
of hooks to your Python code and templates. These hooks are called
18
 
**translation strings**. They tell Django: "This text should be translated into
19
 
the end user's language, if a translation for this text is available in that
20
 
language."
21
 
 
22
 
Django takes care of using these hooks to translate Web apps, on the fly,
23
 
according to users' language preferences.
24
 
 
25
 
Essentially, Django does two things:
26
 
 
27
 
    * It lets developers and template authors specify which parts of their apps
28
 
      should be translatable.
29
 
    * It uses these hooks to translate Web apps for particular users according
30
 
      to their language preferences.
31
 
 
32
 
If you don't need internationalization in your app
33
 
==================================================
34
 
 
35
 
Django's internationalization hooks are on by default, and that means there's a
36
 
bit of i18n-related overhead in certain places of the framework. If you don't
37
 
use internationalization, you should take the two seconds to set
38
 
:setting:`USE_I18N = False <USE_I18N>` in your settings file. If
39
 
:setting:`USE_I18N` is set to ``False``, then Django will make some
40
 
optimizations so as not to load the internationalization machinery.
41
 
 
42
 
You'll probably also want to remove ``'django.core.context_processors.i18n'``
43
 
from your ``TEMPLATE_CONTEXT_PROCESSORS`` setting.
44
 
 
45
 
If you do need internationalization: three steps
46
 
================================================
47
 
 
48
 
    1. Embed translation strings in your Python code and templates.
49
 
    2. Get translations for those strings, in whichever languages you want to
50
 
       support.
51
 
    3. Activate the locale middleware in your Django settings.
52
 
 
53
 
.. admonition:: Behind the scenes
54
 
 
55
 
    Django's translation machinery uses the standard ``gettext`` module that
56
 
    comes with Python.
57
 
 
58
 
1. How to specify translation strings
59
 
=====================================
60
 
 
61
 
Translation strings specify "This text should be translated." These strings can
62
 
appear in your Python code and templates. It's your responsibility to mark
63
 
translatable strings; the system can only translate strings it knows about.
64
 
 
65
 
In Python code
66
 
--------------
67
 
 
68
 
Standard translation
69
 
~~~~~~~~~~~~~~~~~~~~
70
 
 
71
 
Specify a translation string by using the function ``ugettext()``. It's
72
 
convention to import this as a shorter alias, ``_``, to save typing.
73
 
 
74
 
.. note::
75
 
    Python's standard library ``gettext`` module installs ``_()`` into the
76
 
    global namespace, as an alias for ``gettext()``. In Django, we have chosen
77
 
    not to follow this practice, for a couple of reasons:
78
 
 
79
 
      1. For international character set (Unicode) support, ``ugettext()`` is
80
 
         more useful than ``gettext()``. Sometimes, you should be using
81
 
         ``ugettext_lazy()`` as the default translation method for a particular
82
 
         file. Without ``_()`` in the global namespace, the developer has to
83
 
         think about which is the most appropriate translation function.
84
 
 
85
 
      2. The underscore character (``_``) is used to represent "the previous
86
 
         result" in Python's interactive shell and doctest tests. Installing a
87
 
         global ``_()`` function causes interference. Explicitly importing
88
 
         ``ugettext()`` as ``_()`` avoids this problem.
89
 
 
90
 
.. highlightlang:: python
91
 
 
92
 
In this example, the text ``"Welcome to my site."`` is marked as a translation
93
 
string::
94
 
 
95
 
    from django.utils.translation import ugettext as _
96
 
 
97
 
    def my_view(request):
98
 
        output = _("Welcome to my site.")
99
 
        return HttpResponse(output)
100
 
 
101
 
Obviously, you could code this without using the alias. This example is
102
 
identical to the previous one::
103
 
 
104
 
    from django.utils.translation import ugettext
105
 
 
106
 
    def my_view(request):
107
 
        output = ugettext("Welcome to my site.")
108
 
        return HttpResponse(output)
109
 
 
110
 
Translation works on computed values. This example is identical to the previous
111
 
two::
112
 
 
113
 
    def my_view(request):
114
 
        words = ['Welcome', 'to', 'my', 'site.']
115
 
        output = _(' '.join(words))
116
 
        return HttpResponse(output)
117
 
 
118
 
Translation works on variables. Again, here's an identical example::
119
 
 
120
 
    def my_view(request):
121
 
        sentence = 'Welcome to my site.'
122
 
        output = _(sentence)
123
 
        return HttpResponse(output)
124
 
 
125
 
(The caveat with using variables or computed values, as in the previous two
126
 
examples, is that Django's translation-string-detecting utility,
127
 
``django-admin.py makemessages``, won't be able to find these strings. More on
128
 
``makemessages`` later.)
129
 
 
130
 
The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
131
 
specified with Python's standard named-string interpolation syntax. Example::
132
 
 
133
 
    def my_view(request, m, d):
134
 
        output = _('Today is %(month)s, %(day)s.') % {'month': m, 'day': d}
135
 
        return HttpResponse(output)
136
 
 
137
 
This technique lets language-specific translations reorder the placeholder
138
 
text. For example, an English translation may be ``"Today is November, 26."``,
139
 
while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
140
 
placeholders (the month and the day) with their positions swapped.
141
 
 
142
 
For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
143
 
instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
144
 
have more than a single parameter. If you used positional interpolation,
145
 
translations wouldn't be able to reorder placeholder text.
146
 
 
147
 
Marking strings as no-op
148
 
~~~~~~~~~~~~~~~~~~~~~~~~
149
 
 
150
 
Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
151
 
as a translation string without translating it. The string is later translated
152
 
from a variable.
153
 
 
154
 
Use this if you have constant strings that should be stored in the source
155
 
language because they are exchanged over systems or users -- such as strings in
156
 
a database -- but should be translated at the last possible point in time, such
157
 
as when the string is presented to the user.
158
 
 
159
 
.. _lazy-translations:
160
 
 
161
 
Lazy translation
162
 
~~~~~~~~~~~~~~~~
163
 
 
164
 
Use the function ``django.utils.translation.ugettext_lazy()`` to translate
165
 
strings lazily -- when the value is accessed rather than when the
166
 
``ugettext_lazy()`` function is called.
167
 
 
168
 
For example, to translate a model's ``help_text``, do the following::
169
 
 
170
 
    from django.utils.translation import ugettext_lazy
171
 
 
172
 
    class MyThing(models.Model):
173
 
        name = models.CharField(help_text=ugettext_lazy('This is the help text'))
174
 
 
175
 
In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
176
 
not the actual translation. The translation itself will be done when the string
177
 
is used in a string context, such as template rendering on the Django admin
178
 
site.
179
 
 
180
 
The result of a ``ugettext_lazy()`` call can be used wherever you would use a
181
 
unicode string (an object with type ``unicode``) in Python. If you try to use
182
 
it where a bytestring (a ``str`` object) is expected, things will not work as
183
 
expected, since a ``ugettext_lazy()`` object doesn't know how to convert
184
 
itself to a bytestring.  You can't use a unicode string inside a bytestring,
185
 
either, so this is consistent with normal Python behavior. For example::
186
 
 
187
 
    # This is fine: putting a unicode proxy into a unicode string.
188
 
    u"Hello %s" % ugettext_lazy("people")
189
 
 
190
 
    # This will not work, since you cannot insert a unicode object
191
 
    # into a bytestring (nor can you insert our unicode proxy there)
192
 
    "Hello %s" % ugettext_lazy("people")
193
 
 
194
 
If you ever see output that looks like ``"hello
195
 
<django.utils.functional...>"``, you have tried to insert the result of
196
 
``ugettext_lazy()`` into a bytestring. That's a bug in your code.
197
 
 
198
 
If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
199
 
``_`` (underscore), like so::
200
 
 
201
 
    from django.utils.translation import ugettext_lazy as _
202
 
 
203
 
    class MyThing(models.Model):
204
 
        name = models.CharField(help_text=_('This is the help text'))
205
 
 
206
 
Always use lazy translations in :ref:`Django models <topics-db-models>`.
207
 
Field names and table names should be marked for translation (otherwise, they
208
 
won't be translated in the admin interface). This means writing explicit
209
 
``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,
210
 
though, rather than relying on Django's default determination of
211
 
``verbose_name`` and ``verbose_name_plural`` by looking at the model's class
212
 
name::
213
 
 
214
 
    from django.utils.translation import ugettext_lazy as _
215
 
 
216
 
    class MyThing(models.Model):
217
 
        name = models.CharField(_('name'), help_text=_('This is the help text'))
218
 
        class Meta:
219
 
            verbose_name = _('my thing')
220
 
            verbose_name_plural = _('mythings')
221
 
 
222
 
Pluralization
223
 
~~~~~~~~~~~~~
224
 
 
225
 
Use the function ``django.utils.translation.ungettext()`` to specify pluralized
226
 
messages.
227
 
 
228
 
``ungettext`` takes three arguments: the singular translation string, the plural
229
 
translation string and the number of objects.
230
 
 
231
 
This function is useful when your need you Django application to be localizable
232
 
to languages where the number and complexity of `plural forms
233
 
<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
234
 
greater than the two forms used in English ('object' for the singular and
235
 
'objects' for all the cases where ``count`` is different from zero, irrespective
236
 
of its value.)
237
 
 
238
 
For example::
239
 
 
240
 
    from django.utils.translation import ungettext
241
 
    def hello_world(request, count):
242
 
        page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
243
 
            'count': count,
244
 
        }
245
 
        return HttpResponse(page)
246
 
 
247
 
In this example the number of objects is passed to the translation languages as
248
 
the ``count`` variable.
249
 
 
250
 
Lets see a slightly more complex usage example::
251
 
 
252
 
    from django.utils.translation import ungettext
253
 
 
254
 
    count = Report.objects.count()
255
 
    if count == 1:
256
 
        name = Report._meta.verbose_name
257
 
    else:
258
 
        name = Report._meta.verbose_name_plural
259
 
 
260
 
    text = ungettext(
261
 
            'There is %(count)d %(name)s available.',
262
 
            'There are %(count)d %(name)s available.',
263
 
            count
264
 
    ) % {
265
 
        'count': count,
266
 
        'name': name
267
 
    }
268
 
 
269
 
Here we reuse localizable, hopefully already translated literals (contained in
270
 
the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for
271
 
other parts of the sentence so all of it is consistently based on the
272
 
cardinality of the elements at play.
273
 
 
274
 
.. _pluralization-var-notes:
275
 
 
276
 
.. note::
277
 
 
278
 
    When using this technique, make sure you use a single name for every
279
 
    extrapolated variable included in the literal. In the example above note how
280
 
    we used the ``name`` Python variable in both translation strings. This
281
 
    example would fail::
282
 
 
283
 
        from django.utils.translation import ungettext
284
 
        from myapp.models import Report
285
 
 
286
 
        count = Report.objects.count()
287
 
        d = {
288
 
            'count': count,
289
 
            'name': Report._meta.verbose_name
290
 
            'plural_name': Report._meta.verbose_name_plural
291
 
        }
292
 
        text = ungettext(
293
 
                'There is %(count)d %(name)s available.',
294
 
                'There are %(count)d %(plural_name)s available.',
295
 
                count
296
 
        ) % d
297
 
 
298
 
    You would get a ``a format specification for argument 'name', as in
299
 
    'msgstr[0]', doesn't exist in 'msgid'`` error when running
300
 
    ``django-admin.py compilemessages`` or a ``KeyError`` Python exception at
301
 
    runtime.
302
 
 
303
 
In template code
304
 
----------------
305
 
 
306
 
.. highlightlang:: html+django
307
 
 
308
 
Translations in :ref:`Django templates <topics-templates>` uses two template
309
 
tags and a slightly different syntax than in Python code. To give your template
310
 
access to these tags, put ``{% load i18n %}`` toward the top of your template.
311
 
 
312
 
The ``{% trans %}`` template tag translates either a constant string
313
 
(enclosed in single or double quotes) or variable content::
314
 
 
315
 
    <title>{% trans "This is the title." %}</title>
316
 
    <title>{% trans myvar %}</title>
317
 
 
318
 
If the ``noop`` option is present, variable lookup still takes place, but the
319
 
original text will be returned unchanged. This is useful when "stubbing out"
320
 
content that will require translation in the future::
321
 
 
322
 
    <title>{% trans "myvar" noop %}</title>
323
 
 
324
 
Internally, inline translations use an ``ugettext`` call.
325
 
 
326
 
It's not possible to mix a template variable inside a string within ``{% trans
327
 
%}``. If your translations require strings with variables (placeholders), use
328
 
``{% blocktrans %}``::
329
 
 
330
 
    {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
331
 
 
332
 
To translate a template expression -- say, using template filters -- you need
333
 
to bind the expression to a local variable for use within the translation
334
 
block::
335
 
 
336
 
    {% blocktrans with value|filter as myvar %}
337
 
    This will have {{ myvar }} inside.
338
 
    {% endblocktrans %}
339
 
 
340
 
If you need to bind more than one expression inside a ``blocktrans`` tag,
341
 
separate the pieces with ``and``::
342
 
 
343
 
    {% blocktrans with book|title as book_t and author|title as author_t %}
344
 
    This is {{ book_t }} by {{ author_t }}
345
 
    {% endblocktrans %}
346
 
 
347
 
To pluralize, specify both the singular and plural forms with the
348
 
``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and
349
 
``{% endblocktrans %}``. Example::
350
 
 
351
 
    {% blocktrans count list|length as counter %}
352
 
    There is only one {{ name }} object.
353
 
    {% plural %}
354
 
    There are {{ counter }} {{ name }} objects.
355
 
    {% endblocktrans %}
356
 
 
357
 
When you use the pluralization feature and bind additional values to local
358
 
variables apart from the counter value that selects the translated literal to be
359
 
used, have in mind that the ``blocktrans`` construct is internally converted
360
 
to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext
361
 
variables <pluralization-var-notes>` apply.
362
 
 
363
 
Each ``RequestContext`` has access to three translation-specific variables:
364
 
 
365
 
    * ``LANGUAGES`` is a list of tuples in which the first element is the
366
 
      language code and the second is the language name (translated into the
367
 
      currently active locale).
368
 
 
369
 
    * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
370
 
      Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`,
371
 
      below.)
372
 
 
373
 
    * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
374
 
      right-to-left language, e.g.: Hebrew, Arabic. If False it's a
375
 
      left-to-right language, e.g.: English, French, German etc.
376
 
 
377
 
 
378
 
If you don't use the ``RequestContext`` extension, you can get those values with
379
 
three tags::
380
 
 
381
 
    {% get_current_language as LANGUAGE_CODE %}
382
 
    {% get_available_languages as LANGUAGES %}
383
 
    {% get_current_language_bidi as LANGUAGE_BIDI %}
384
 
 
385
 
These tags also require a ``{% load i18n %}``.
386
 
 
387
 
Translation hooks are also available within any template block tag that accepts
388
 
constant strings. In those cases, just use ``_()`` syntax to specify a
389
 
translation string::
390
 
 
391
 
    {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
392
 
 
393
 
In this case, both the tag and the filter will see the already-translated
394
 
string, so they don't need to be aware of translations.
395
 
 
396
 
.. note::
397
 
    In this example, the translation infrastructure will be passed the string
398
 
    ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
399
 
    translated string will need to contain the comma so that the filter
400
 
    parsing code knows how to split up the arguments. For example, a German
401
 
    translator might translate the string ``"yes,no"`` as ``"ja,nein"``
402
 
    (keeping the comma intact).
403
 
 
404
 
.. _Django templates: ../templates_python/
405
 
 
406
 
Working with lazy translation objects
407
 
-------------------------------------
408
 
 
409
 
.. highlightlang:: python
410
 
 
411
 
Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
412
 
and utility functions is a common operation. When you're working with these
413
 
objects elsewhere in your code, you should ensure that you don't accidentally
414
 
convert them to strings, because they should be converted as late as possible
415
 
(so that the correct locale is in effect). This necessitates the use of a
416
 
couple of helper functions.
417
 
 
418
 
Joining strings: string_concat()
419
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
420
 
 
421
 
Standard Python string joins (``''.join([...])``) will not work on lists
422
 
containing lazy translation objects. Instead, you can use
423
 
``django.utils.translation.string_concat()``, which creates a lazy object that
424
 
concatenates its contents *and* converts them to strings only when the result
425
 
is included in a string. For example::
426
 
 
427
 
    from django.utils.translation import string_concat
428
 
    ...
429
 
    name = ugettext_lazy(u'John Lennon')
430
 
    instrument = ugettext_lazy(u'guitar')
431
 
    result = string_concat([name, ': ', instrument])
432
 
 
433
 
In this case, the lazy translations in ``result`` will only be converted to
434
 
strings when ``result`` itself is used in a string (usually at template
435
 
rendering time).
436
 
 
437
 
The allow_lazy() decorator
438
 
~~~~~~~~~~~~~~~~~~~~~~~~~~
439
 
 
440
 
Django offers many utility functions (particularly in ``django.utils``) that
441
 
take a string as their first argument and do something to that string. These
442
 
functions are used by template filters as well as directly in other code.
443
 
 
444
 
If you write your own similar functions and deal with translations, you'll
445
 
face the problem of what to do when the first argument is a lazy translation
446
 
object. You don't want to convert it to a string immediately, because you might
447
 
be using this function outside of a view (and hence the current thread's locale
448
 
setting will not be correct).
449
 
 
450
 
For cases like this, use the ``django.utils.functional.allow_lazy()``
451
 
decorator. It modifies the function so that *if* it's called with a lazy
452
 
translation as the first argument, the function evaluation is delayed until it
453
 
needs to be converted to a string.
454
 
 
455
 
For example::
456
 
 
457
 
    from django.utils.functional import allow_lazy
458
 
 
459
 
    def fancy_utility_function(s, ...):
460
 
        # Do some conversion on string 's'
461
 
        ...
462
 
    fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
463
 
 
464
 
The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
465
 
a number of extra arguments (``*args``) specifying the type(s) that the
466
 
original function can return. Usually, it's enough to include ``unicode`` here
467
 
and ensure that your function returns only Unicode strings.
468
 
 
469
 
Using this decorator means you can write your function and assume that the
470
 
input is a proper string, then add support for lazy translation objects at the
471
 
end.
472
 
 
473
 
.. _how-to-create-language-files:
474
 
 
475
 
2. How to create language files
476
 
===============================
477
 
 
478
 
Once you've tagged your strings for later translation, you need to write (or
479
 
obtain) the language translations themselves. Here's how that works.
480
 
 
481
 
.. admonition:: Locale restrictions
482
 
 
483
 
    Django does not support localizing your application into a locale for
484
 
    which Django itself has not been translated. In this case, it will ignore
485
 
    your translation files. If you were to try this and Django supported it,
486
 
    you would inevitably see a mixture of translated strings (from your
487
 
    application) and English strings (from Django itself). If you want to
488
 
    support a locale for your application that is not already part of
489
 
    Django, you'll need to make at least a minimal translation of the Django
490
 
    core. See the relevant :ref:`LocaleMiddleware note<locale-middleware-notes>`
491
 
    for more details.
492
 
 
493
 
Message files
494
 
-------------
495
 
 
496
 
The first step is to create a **message file** for a new language. A message
497
 
file is a plain-text file, representing a single language, that contains all
498
 
available translation strings and how they should be represented in the given
499
 
language. Message files have a ``.po`` file extension.
500
 
 
501
 
Django comes with a tool, ``django-admin.py makemessages``, that automates the
502
 
creation and upkeep of these files.
503
 
 
504
 
.. admonition:: A note to Django veterans
505
 
 
506
 
    The old tool ``bin/make-messages.py`` has been moved to the command
507
 
    ``django-admin.py makemessages`` to provide consistency throughout Django.
508
 
 
509
 
To create or update a message file, run this command::
510
 
 
511
 
    django-admin.py makemessages -l de
512
 
 
513
 
...where ``de`` is the language code for the message file you want to create.
514
 
The language code, in this case, is in locale format. For example, it's
515
 
``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German.
516
 
 
517
 
The script should be run from one of three places:
518
 
 
519
 
    * The root directory of your Django project.
520
 
    * The root directory of your Django app.
521
 
    * The root ``django`` directory (not a Subversion checkout, but the one
522
 
      that is linked-to via ``$PYTHONPATH`` or is located somewhere on that
523
 
      path). This is only relevant when you are creating a translation for
524
 
      Django itself, see :ref:`contributing-translations`.
525
 
 
526
 
The script runs over your project source tree or your application source tree
527
 
and pulls out all strings marked for translation. It creates (or updates) a
528
 
message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``
529
 
example, the file will be ``locale/de/LC_MESSAGES/django.po``.
530
 
 
531
 
By default ``django-admin.py makemessages`` examines every file that has the
532
 
``.html`` file extension. In case you want to override that default, use the
533
 
``--extension`` or ``-e`` option to specify the file extensions to examine::
534
 
 
535
 
    django-admin.py makemessages -l de -e txt
536
 
 
537
 
Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
538
 
multiple times::
539
 
 
540
 
    django-admin.py makemessages -l=de -e=html,txt -e xml
541
 
 
542
 
When `creating JavaScript translation catalogs`_ you need to use the special
543
 
'djangojs' domain, **not** ``-e js``.
544
 
 
545
 
.. _create a JavaScript translation catalog: `Creating JavaScript translation catalogs`_
546
 
 
547
 
.. admonition:: No gettext?
548
 
 
549
 
    If you don't have the ``gettext`` utilities installed, ``django-admin.py
550
 
    makemessages`` will create empty files. If that's the case, either install
551
 
    the ``gettext`` utilities or just copy the English message file
552
 
    (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
553
 
    point; it's just an empty translation file.
554
 
 
555
 
.. admonition:: Working on Windows?
556
 
 
557
 
   If you're using Windows and need to install the GNU gettext utilities so
558
 
   ``django-admin makemessages`` works see `gettext on Windows`_ for more
559
 
   information.
560
 
 
561
 
The format of ``.po`` files is straightforward. Each ``.po`` file contains a
562
 
small bit of metadata, such as the translation maintainer's contact
563
 
information, but the bulk of the file is a list of **messages** -- simple
564
 
mappings between translation strings and the actual translated text for the
565
 
particular language.
566
 
 
567
 
For example, if your Django app contained a translation string for the text
568
 
``"Welcome to my site."``, like so::
569
 
 
570
 
    _("Welcome to my site.")
571
 
 
572
 
...then ``django-admin.py makemessages`` will have created a ``.po`` file
573
 
containing the following snippet -- a message::
574
 
 
575
 
    #: path/to/python/module.py:23
576
 
    msgid "Welcome to my site."
577
 
    msgstr ""
578
 
 
579
 
A quick explanation:
580
 
 
581
 
    * ``msgid`` is the translation string, which appears in the source. Don't
582
 
      change it.
583
 
    * ``msgstr`` is where you put the language-specific translation. It starts
584
 
      out empty, so it's your responsibility to change it. Make sure you keep
585
 
      the quotes around your translation.
586
 
    * As a convenience, each message includes, in the form of a comment line
587
 
      prefixed with ``#`` and located above the ``msgid`` line, the filename and
588
 
      line number from which the translation string was gleaned.
589
 
 
590
 
Long messages are a special case. There, the first string directly after the
591
 
``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
592
 
written over the next few lines as one string per line. Those strings are
593
 
directly concatenated. Don't forget trailing spaces within the strings;
594
 
otherwise, they'll be tacked together without whitespace!
595
 
 
596
 
.. admonition:: Mind your charset
597
 
 
598
 
    When creating a PO file with your favorite text editor, first edit
599
 
    the charset line (search for ``"CHARSET"``) and set it to the charset
600
 
    you'll be using to edit the content. Due to the way the ``gettext`` tools
601
 
    work internally and because we want to allow non-ASCII source strings in
602
 
    Django's core and your applications, you **must** use UTF-8 as the encoding
603
 
    for your PO file. This means that everybody will be using the same
604
 
    encoding, which is important when Django processes the PO files.
605
 
 
606
 
To reexamine all source code and templates for new translation strings and
607
 
update all message files for **all** languages, run this::
608
 
 
609
 
    django-admin.py makemessages -a
610
 
 
611
 
Compiling message files
612
 
-----------------------
613
 
 
614
 
After you create your message file -- and each time you make changes to it --
615
 
you'll need to compile it into a more efficient form, for use by ``gettext``.
616
 
Do this with the ``django-admin.py compilemessages`` utility.
617
 
 
618
 
This tool runs over all available ``.po`` files and creates ``.mo`` files, which
619
 
are binary files optimized for use by ``gettext``. In the same directory from
620
 
which you ran ``django-admin.py makemessages``, run ``django-admin.py
621
 
compilemessages`` like this::
622
 
 
623
 
   django-admin.py compilemessages
624
 
 
625
 
That's it. Your translations are ready for use.
626
 
 
627
 
.. admonition:: A note to Django veterans
628
 
 
629
 
    The old tool ``bin/compile-messages.py`` has been moved to the command
630
 
    ``django-admin.py compilemessages`` to provide consistency throughout
631
 
    Django.
632
 
 
633
 
.. admonition:: Working on Windows?
634
 
 
635
 
   If you're using Windows and need to install the GNU gettext utilities so
636
 
   ``django-admin compilemessages`` works see `gettext on Windows`_ for more
637
 
   information.
638
 
 
639
 
.. _how-django-discovers-language-preference:
640
 
 
641
 
3. How Django discovers language preference
642
 
===========================================
643
 
 
644
 
Once you've prepared your translations -- or, if you just want to use the
645
 
translations that come with Django -- you'll just need to activate translation
646
 
for your app.
647
 
 
648
 
Behind the scenes, Django has a very flexible model of deciding which language
649
 
should be used -- installation-wide, for a particular user, or both.
650
 
 
651
 
To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
652
 
Django uses this language as the default translation -- the final attempt if no
653
 
other translator finds a translation.
654
 
 
655
 
If all you want to do is run Django with your native language, and a language
656
 
file is available for your language, all you need to do is set
657
 
``LANGUAGE_CODE``.
658
 
 
659
 
If you want to let each individual user specify which language he or she
660
 
prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
661
 
selection based on data from the request. It customizes content for each user.
662
 
 
663
 
To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
664
 
to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you
665
 
should follow these guidelines:
666
 
 
667
 
    * Make sure it's one of the first middlewares installed.
668
 
    * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
669
 
      makes use of session data.
670
 
    * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
671
 
 
672
 
For example, your ``MIDDLEWARE_CLASSES`` might look like this::
673
 
 
674
 
    MIDDLEWARE_CLASSES = (
675
 
       'django.contrib.sessions.middleware.SessionMiddleware',
676
 
       'django.middleware.locale.LocaleMiddleware',
677
 
       'django.middleware.common.CommonMiddleware',
678
 
    )
679
 
 
680
 
(For more on middleware, see the :ref:`middleware documentation
681
 
<topics-http-middleware>`.)
682
 
 
683
 
``LocaleMiddleware`` tries to determine the user's language preference by
684
 
following this algorithm:
685
 
 
686
 
    * First, it looks for a ``django_language`` key in the current user's
687
 
      session.
688
 
 
689
 
    * Failing that, it looks for a cookie.
690
 
 
691
 
      .. versionchanged:: 1.0
692
 
 
693
 
      In Django version 0.96 and before, the cookie's name is hard-coded to
694
 
      ``django_language``. In Django 1,0, The cookie name is set by the
695
 
      ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
696
 
      ``django_language``.)
697
 
 
698
 
    * Failing that, it looks at the ``Accept-Language`` HTTP header. This
699
 
      header is sent by your browser and tells the server which language(s) you
700
 
      prefer, in order by priority. Django tries each language in the header
701
 
      until it finds one with available translations.
702
 
 
703
 
    * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
704
 
 
705
 
.. _locale-middleware-notes:
706
 
 
707
 
Notes:
708
 
 
709
 
    * In each of these places, the language preference is expected to be in the
710
 
      standard language format, as a string. For example, Brazilian Portuguese
711
 
      is ``pt-br``.
712
 
 
713
 
    * If a base language is available but the sublanguage specified is not,
714
 
      Django uses the base language. For example, if a user specifies ``de-at``
715
 
      (Austrian German) but Django only has ``de`` available, Django uses
716
 
      ``de``.
717
 
 
718
 
    * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
719
 
      If you want to restrict the language selection to a subset of provided
720
 
      languages (because your application doesn't provide all those languages),
721
 
      set ``LANGUAGES`` to a list of languages. For example::
722
 
 
723
 
          LANGUAGES = (
724
 
            ('de', _('German')),
725
 
            ('en', _('English')),
726
 
          )
727
 
 
728
 
      This example restricts languages that are available for automatic
729
 
      selection to German and English (and any sublanguage, like de-ch or
730
 
      en-us).
731
 
 
732
 
      .. _LANGUAGES setting: ../settings/#languages
733
 
 
734
 
    * If you define a custom ``LANGUAGES`` setting, as explained in the
735
 
      previous bullet, it's OK to mark the languages as translation strings
736
 
      -- but use a "dummy" ``ugettext()`` function, not the one in
737
 
      ``django.utils.translation``. You should *never* import
738
 
      ``django.utils.translation`` from within your settings file, because that
739
 
      module in itself depends on the settings, and that would cause a circular
740
 
      import.
741
 
 
742
 
      The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
743
 
      settings file::
744
 
 
745
 
          ugettext = lambda s: s
746
 
 
747
 
          LANGUAGES = (
748
 
              ('de', ugettext('German')),
749
 
              ('en', ugettext('English')),
750
 
          )
751
 
 
752
 
      With this arrangement, ``django-admin.py makemessages`` will still find
753
 
      and mark these strings for translation, but the translation won't happen
754
 
      at runtime -- so you'll have to remember to wrap the languages in the
755
 
      *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
756
 
 
757
 
    * The ``LocaleMiddleware`` can only select languages for which there is a
758
 
      Django-provided base translation. If you want to provide translations
759
 
      for your application that aren't already in the set of translations
760
 
      in Django's source tree, you'll want to provide at least basic
761
 
      translations for that language. For example, Django uses technical
762
 
      message IDs to translate date formats and time formats -- so you will
763
 
      need at least those translations for the system to work correctly.
764
 
 
765
 
      A good starting point is to copy the English ``.po`` file and to
766
 
      translate at least the technical messages -- maybe the validation
767
 
      messages, too.
768
 
 
769
 
      Technical message IDs are easily recognized; they're all upper case. You
770
 
      don't translate the message ID as with other messages, you provide the
771
 
      correct local variant on the provided English value. For example, with
772
 
      ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would
773
 
      be the format string that you want to use in your language. The format
774
 
      is identical to the format strings used by the ``now`` template tag.
775
 
 
776
 
Once ``LocaleMiddleware`` determines the user's preference, it makes this
777
 
preference available as ``request.LANGUAGE_CODE`` for each
778
 
:class:`~django.http.HttpRequest`. Feel free to read this value in your view
779
 
code. Here's a simple example::
780
 
 
781
 
    def hello_world(request, count):
782
 
        if request.LANGUAGE_CODE == 'de-at':
783
 
            return HttpResponse("You prefer to read Austrian German.")
784
 
        else:
785
 
            return HttpResponse("You prefer to read another language.")
786
 
 
787
 
Note that, with static (middleware-less) translation, the language is in
788
 
``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
789
 
in ``request.LANGUAGE_CODE``.
790
 
 
791
 
.. _settings file: ../settings/
792
 
.. _middleware documentation: ../middleware/
793
 
.. _session: ../sessions/
794
 
.. _request object: ../request_response/#httprequest-objects
795
 
 
796
 
.. _translations-in-your-own-projects:
797
 
 
798
 
Using translations in your own projects
799
 
=======================================
800
 
 
801
 
Django looks for translations by following this algorithm:
802
 
 
803
 
    * First, it looks for a ``locale`` directory in the application directory
804
 
      of the view that's being called. If it finds a translation for the
805
 
      selected language, the translation will be installed.
806
 
    * Next, it looks for a ``locale`` directory in the project directory. If it
807
 
      finds a translation, the translation will be installed.
808
 
    * Finally, it checks the Django-provided base translation in
809
 
      ``django/conf/locale``.
810
 
 
811
 
This way, you can write applications that include their own translations, and
812
 
you can override base translations in your project path. Or, you can just build
813
 
a big project out of several apps and put all translations into one big project
814
 
message file. The choice is yours.
815
 
 
816
 
.. note::
817
 
 
818
 
    If you're using manually configured settings, as described
819
 
    :ref:`settings-without-django-settings-module`, the ``locale`` directory in
820
 
    the project directory will not be examined, since Django loses the ability
821
 
    to work out the location of the project directory. (Django normally uses the
822
 
    location of the settings file to determine this, and a settings file doesn't
823
 
    exist if you're manually configuring your settings.)
824
 
 
825
 
All message file repositories are structured the same way. They are:
826
 
 
827
 
    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
828
 
    * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
829
 
    * All paths listed in ``LOCALE_PATHS`` in your settings file are
830
 
      searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
831
 
    * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
832
 
 
833
 
To create message files, you use the same ``django-admin.py makemessages``
834
 
tool as with the Django message files. You only need to be in the right place
835
 
tree) or the ``locale/`` (in case of app messages or project messages)
836
 
directory are located. And you use the same ``django-admin.py compilemessages``
837
 
to produce the binary ``django.mo`` files that are used by ``gettext``.
838
 
 
839
 
You can also run ``django-admin.py compilemessages --settings=path.to.settings``
840
 
to make the compiler process all the directories in your ``LOCALE_PATHS``
841
 
setting.
842
 
 
843
 
Application message files are a bit complicated to discover -- they need the
844
 
``LocaleMiddleware``. If you don't use the middleware, only the Django message
845
 
files and project message files will be processed.
846
 
 
847
 
Finally, you should give some thought to the structure of your translation
848
 
files. If your applications need to be delivered to other users and will
849
 
be used in other projects, you might want to use app-specific translations.
850
 
But using app-specific translations and project translations could produce
851
 
weird problems with ``makemessages``: ``makemessages`` will traverse all
852
 
directories below the current path and so might put message IDs into the
853
 
project message file that are already in application message files.
854
 
 
855
 
The easiest way out is to store applications that are not part of the project
856
 
(and so carry their own translations) outside the project tree. That way,
857
 
``django-admin.py makemessages`` on the project level will only translate
858
 
strings that are connected to your explicit project and not strings that are
859
 
distributed independently.
860
 
 
861
 
The ``set_language`` redirect view
862
 
==================================
863
 
 
864
 
As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
865
 
that sets a user's language preference and redirects back to the previous page.
866
 
 
867
 
Activate this view by adding the following line to your URLconf::
868
 
 
869
 
    (r'^i18n/', include('django.conf.urls.i18n')),
870
 
 
871
 
(Note that this example makes the view available at ``/i18n/setlang/``.)
872
 
 
873
 
The view expects to be called via the ``POST`` method, with a ``language``
874
 
parameter set in request. If session support is enabled, the view
875
 
saves the language choice in the user's session. Otherwise, it saves the
876
 
language choice in a cookie that is by default named ``django_language``.
877
 
(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
878
 
 
879
 
After setting the language choice, Django redirects the user, following this
880
 
algorithm:
881
 
 
882
 
    * Django looks for a ``next`` parameter in the ``POST`` data.
883
 
    * If that doesn't exist, or is empty, Django tries the URL in the
884
 
      ``Referrer`` header.
885
 
    * If that's empty -- say, if a user's browser suppresses that header --
886
 
      then the user will be redirected to ``/`` (the site root) as a fallback.
887
 
 
888
 
Here's example HTML template code:
889
 
 
890
 
.. code-block:: html+django
891
 
 
892
 
    <form action="/i18n/setlang/" method="post">
893
 
    <input name="next" type="hidden" value="/next/page/" />
894
 
    <select name="language">
895
 
    {% for lang in LANGUAGES %}
896
 
    <option value="{{ lang.0 }}">{{ lang.1 }}</option>
897
 
    {% endfor %}
898
 
    </select>
899
 
    <input type="submit" value="Go" />
900
 
    </form>
901
 
 
902
 
Translations and JavaScript
903
 
===========================
904
 
 
905
 
Adding translations to JavaScript poses some problems:
906
 
 
907
 
    * JavaScript code doesn't have access to a ``gettext`` implementation.
908
 
 
909
 
    * JavaScript code doesn't have access to .po or .mo files; they need to be
910
 
      delivered by the server.
911
 
 
912
 
    * The translation catalogs for JavaScript should be kept as small as
913
 
      possible.
914
 
 
915
 
Django provides an integrated solution for these problems: It passes the
916
 
translations into JavaScript, so you can call ``gettext``, etc., from within
917
 
JavaScript.
918
 
 
919
 
The ``javascript_catalog`` view
920
 
-------------------------------
921
 
 
922
 
The main solution to these problems is the ``javascript_catalog`` view, which
923
 
sends out a JavaScript code library with functions that mimic the ``gettext``
924
 
interface, plus an array of translation strings. Those translation strings are
925
 
taken from the application, project or Django core, according to what you
926
 
specify in either the info_dict or the URL.
927
 
 
928
 
You hook it up like this::
929
 
 
930
 
    js_info_dict = {
931
 
        'packages': ('your.app.package',),
932
 
    }
933
 
 
934
 
    urlpatterns = patterns('',
935
 
        (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
936
 
    )
937
 
 
938
 
Each string in ``packages`` should be in Python dotted-package syntax (the
939
 
same format as the strings in ``INSTALLED_APPS``) and should refer to a package
940
 
that contains a ``locale`` directory. If you specify multiple packages, all
941
 
those catalogs are merged into one catalog. This is useful if you have
942
 
JavaScript that uses strings from different applications.
943
 
 
944
 
You can make the view dynamic by putting the packages into the URL pattern::
945
 
 
946
 
    urlpatterns = patterns('',
947
 
        (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
948
 
    )
949
 
 
950
 
With this, you specify the packages as a list of package names delimited by '+'
951
 
signs in the URL. This is especially useful if your pages use code from
952
 
different apps and this changes often and you don't want to pull in one big
953
 
catalog file. As a security measure, these values can only be either
954
 
``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
955
 
 
956
 
Using the JavaScript translation catalog
957
 
----------------------------------------
958
 
 
959
 
To use the catalog, just pull in the dynamically generated script like this::
960
 
 
961
 
    <script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
962
 
 
963
 
This uses reverse URL lookup to find the URL of the JavaScript catalog view.
964
 
When the catalog is loaded, your JavaScript code can use the standard
965
 
``gettext`` interface to access it::
966
 
 
967
 
    document.write(gettext('this is to be translated'));
968
 
 
969
 
There is also an ``ngettext`` interface::
970
 
 
971
 
    var object_cnt = 1 // or 0, or 2, or 3, ...
972
 
    s = ngettext('literal for the singular case',
973
 
            'literal for the plural case', object_cnt);
974
 
 
975
 
and even a string interpolation function::
976
 
 
977
 
    function interpolate(fmt, obj, named);
978
 
 
979
 
The interpolation syntax is borrowed from Python, so the ``interpolate``
980
 
function supports both positional and named interpolation:
981
 
 
982
 
    * Positional interpolation: ``obj`` contains a JavaScript Array object
983
 
      whose elements values are then sequentially interpolated in their
984
 
      corresponding ``fmt`` placeholders in the same order they appear.
985
 
      For example::
986
 
 
987
 
        fmts = ngettext('There is %s object. Remaining: %s',
988
 
                'There are %s objects. Remaining: %s', 11);
989
 
        s = interpolate(fmts, [11, 20]);
990
 
        // s is 'There are 11 objects. Remaining: 20'
991
 
 
992
 
    * Named interpolation: This mode is selected by passing the optional
993
 
      boolean ``named`` parameter as true. ``obj`` contains a JavaScript
994
 
      object or associative array. For example::
995
 
 
996
 
        d = {
997
 
            count: 10
998
 
            total: 50
999
 
        };
1000
 
 
1001
 
        fmts = ngettext('Total: %(total)s, there is %(count)s object',
1002
 
        'there are %(count)s of a total of %(total)s objects', d.count);
1003
 
        s = interpolate(fmts, d, true);
1004
 
 
1005
 
You shouldn't go over the top with string interpolation, though: this is still
1006
 
JavaScript, so the code has to make repeated regular-expression substitutions.
1007
 
This isn't as fast as string interpolation in Python, so keep it to those
1008
 
cases where you really need it (for example, in conjunction with ``ngettext``
1009
 
to produce proper pluralizations).
1010
 
 
1011
 
Creating JavaScript translation catalogs
1012
 
----------------------------------------
1013
 
 
1014
 
You create and update the translation catalogs the same way as the other
1015
 
 
1016
 
Django translation catalogs -- with the django-admin.py makemessages tool. The
1017
 
only difference is you need to provide a ``-d djangojs`` parameter, like this::
1018
 
 
1019
 
    django-admin.py makemessages -d djangojs -l de
1020
 
 
1021
 
This would create or update the translation catalog for JavaScript for German.
1022
 
After updating translation catalogs, just run ``django-admin.py compilemessages``
1023
 
the same way as you do with normal Django translation catalogs.
1024
 
 
1025
 
Specialties of Django translation
1026
 
==================================
1027
 
 
1028
 
If you know ``gettext``, you might note these specialties in the way Django
1029
 
does translation:
1030
 
 
1031
 
    * The string domain is ``django`` or ``djangojs``. This string domain is
1032
 
      used to differentiate between different programs that store their data
1033
 
      in a common message-file library (usually ``/usr/share/locale/``). The
1034
 
      ``django`` domain is used for python and template translation strings
1035
 
      and is loaded into the global translation catalogs. The ``djangojs``
1036
 
      domain is only used for JavaScript translation catalogs to make sure
1037
 
      that those are as small as possible.
1038
 
    * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
1039
 
      ``xgettext`` and ``msgfmt``. This is mostly for convenience.
1040
 
 
1041
 
``gettext`` on Windows
1042
 
======================
1043
 
 
1044
 
This is only needed for people who either want to extract message IDs or compile
1045
 
message files (``.po``). Translation work itself just involves editing existing
1046
 
files of this type, but if you want to create your own message files, or want to
1047
 
test or compile a changed message file, you will need the ``gettext`` utilities:
1048
 
 
1049
 
    * Download the following zip files from the GNOME servers
1050
 
      http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
1051
 
      of its mirrors_
1052
 
 
1053
 
      * ``gettext-runtime-X.zip``
1054
 
      * ``gettext-tools-X.zip``
1055
 
 
1056
 
      ``X`` is the version number, we recomend using ``0.15`` or higher.
1057
 
 
1058
 
    * Extract the contents of the ``bin\`` directories in both files to the
1059
 
      same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
1060
 
 
1061
 
    * Update the system PATH:
1062
 
 
1063
 
      * ``Control Panel > System > Advanced > Environment Variables``
1064
 
      * In the ``System variables`` list, click ``Path``, click ``Edit``
1065
 
      * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
1066
 
        ``Variable value`` field
1067
 
 
1068
 
.. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
1069
 
 
1070
 
You may also use ``gettext`` binaries you have obtained elsewhere, so long as
1071
 
the ``xgettext --version`` command works properly. Some version 0.14.4 binaries
1072
 
have been found to not support this command. Do not attempt to use Django
1073
 
translation utilities with a ``gettext`` package if the command ``xgettext
1074
 
--version`` entered at a Windows command prompt causes a popup window saying
1075
 
"xgettext.exe has generated errors and will be closed by Windows".