Ticket #10260: i18n-doc-rf.diff

File i18n-doc-rf.diff, 87.3 KB (added by Ramiro Morales, 16 years ago)
  • docs/internals/contributing.txt

    diff --git a/docs/internals/contributing.txt b/docs/internals/contributing.txt
    a b  
    402402
    403403    * Join the `Django i18n mailing list`_ and introduce yourself.
    404404
    405     * Create translations using the methods described in the
    406       :ref:`i18n documentation <topics-i18n>`. For this you will use the
    407       ``django-admin.py makemessages`` tool. In this particular case it should
    408       be run from the top-level ``django`` directory of the Django source tree.
     405    * Create translations using the methods described in the
     406      :ref:`i18n documentation <topics-i18n-localization>`. For this you will use
     407      the ``django-admin.py makemessages`` tool. In this particular case it
     408      should be run from the top-level ``django`` directory of the Django
     409      source tree.
    409410
    410411      The script runs over the entire Django source tree and pulls out all
    411412      strings marked for translation. It creates (or updates) a message file in
    412       the directory ``conf/locale`` (for example for ``pt-BR``, the file will be
    413       ``conf/locale/pt-br/LC_MESSAGES/django.po``).
     413      the directory ``conf/locale`` (for example for ``pt_BR``, the file will be
     414      ``conf/locale/pt_BR/LC_MESSAGES/django.po``).
    414415
    415416    * Make sure that ``django-admin.py compilemessages -l <lang>`` runs without
    416417      producing any warnings.
     
    426427
    427428.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
    428429
     430.. _technical-messages:
     431
     432Django technical message IDs
     433----------------------------
     434
     435Django uses technical message IDs to translate date formats and time formats.
     436Technical message IDs are easily recognized; they're all upper case. You
     437don't translate the message ID as with other messages, you provide the
     438correct local variant on the provided English value. For example, with
     439``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would
     440be the format string that you want to use in your language. The format
     441is identical to the format strings used by the ``now`` template tag.
     442
    429443Coding style
    430444============
    431445
  • deleted file docs/topics/i18n.txt

    diff --git a/docs/topics/i18n.txt b/docs/topics/i18n.txt
    deleted file mode 100644
    + -  
    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. Example::
    227 
    228     from django.utils.translation import ungettext
    229     def hello_world(request, count):
    230         page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
    231             'count': count,
    232         }
    233         return HttpResponse(page)
    234 
    235 ``ungettext`` takes three arguments: the singular translation string, the plural
    236 translation string and the number of objects (which is passed to the
    237 translation languages as the ``count`` variable).
    238 
    239 In template code
    240 ----------------
    241 
    242 .. highlightlang:: html+django
    243 
    244 Translations in :ref:`Django templates <topics-templates>` uses two template
    245 tags and a slightly different syntax than in Python code. To give your template
    246 access to these tags, put ``{% load i18n %}`` toward the top of your template.
    247 
    248 The ``{% trans %}`` template tag translates either a constant string
    249 (enclosed in single or double quotes) or variable content::
    250 
    251     <title>{% trans "This is the title." %}</title>
    252     <title>{% trans myvar %}</title>
    253 
    254 If the ``noop`` option is present, variable lookup still takes place but the
    255 translation is skipped. This is useful when "stubbing out" content that will
    256 require translation in the future::
    257 
    258     <title>{% trans "myvar" noop %}</title>
    259 
    260 It's not possible to mix a template variable inside a string within ``{% trans
    261 %}``. If your translations require strings with variables (placeholders), use
    262 ``{% blocktrans %}``::
    263 
    264     {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
    265 
    266 To translate a template expression -- say, using template filters -- you need
    267 to bind the expression to a local variable for use within the translation
    268 block::
    269 
    270     {% blocktrans with value|filter as myvar %}
    271     This will have {{ myvar }} inside.
    272     {% endblocktrans %}
    273 
    274 If you need to bind more than one expression inside a ``blocktrans`` tag,
    275 separate the pieces with ``and``::
    276 
    277     {% blocktrans with book|title as book_t and author|title as author_t %}
    278     This is {{ book_t }} by {{ author_t }}
    279     {% endblocktrans %}
    280 
    281 To pluralize, specify both the singular and plural forms with the
    282 ``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and
    283 ``{% endblocktrans %}``. Example::
    284 
    285     {% blocktrans count list|length as counter %}
    286     There is only one {{ name }} object.
    287     {% plural %}
    288     There are {{ counter }} {{ name }} objects.
    289     {% endblocktrans %}
    290 
    291 Internally, all block and inline translations use the appropriate
    292 ``ugettext`` / ``ungettext`` call.
    293 
    294 Each ``RequestContext`` has access to three translation-specific variables:
    295 
    296     * ``LANGUAGES`` is a list of tuples in which the first element is the
    297       language code and the second is the language name (translated into the
    298       currently active locale).
    299 
    300     * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
    301       Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`,
    302       below.)
    303 
    304     * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
    305       right-to-left language, e.g.: Hebrew, Arabic. If False it's a
    306       left-to-right language, e.g.: English, French, German etc.
    307 
    308 
    309 If you don't use the ``RequestContext`` extension, you can get those values with
    310 three tags::
    311 
    312     {% get_current_language as LANGUAGE_CODE %}
    313     {% get_available_languages as LANGUAGES %}
    314     {% get_current_language_bidi as LANGUAGE_BIDI %}
    315 
    316 These tags also require a ``{% load i18n %}``.
    317 
    318 Translation hooks are also available within any template block tag that accepts
    319 constant strings. In those cases, just use ``_()`` syntax to specify a
    320 translation string::
    321 
    322     {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
    323 
    324 In this case, both the tag and the filter will see the already-translated
    325 string, so they don't need to be aware of translations.
    326 
    327 .. note::
    328     In this example, the translation infrastructure will be passed the string
    329     ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
    330     translated string will need to contain the comma so that the filter
    331     parsing code knows how to split up the arguments. For example, a German
    332     translator might translate the string ``"yes,no"`` as ``"ja,nein"``
    333     (keeping the comma intact).
    334 
    335 .. _Django templates: ../templates_python/
    336 
    337 Working with lazy translation objects
    338 -------------------------------------
    339 
    340 .. highlightlang:: python
    341 
    342 Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
    343 and utility functions is a common operation. When you're working with these
    344 objects elsewhere in your code, you should ensure that you don't accidentally
    345 convert them to strings, because they should be converted as late as possible
    346 (so that the correct locale is in effect). This necessitates the use of a
    347 couple of helper functions.
    348 
    349 Joining strings: string_concat()
    350 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    351 
    352 Standard Python string joins (``''.join([...])``) will not work on lists
    353 containing lazy translation objects. Instead, you can use
    354 ``django.utils.translation.string_concat()``, which creates a lazy object that
    355 concatenates its contents *and* converts them to strings only when the result
    356 is included in a string. For example::
    357 
    358     from django.utils.translation import string_concat
    359     ...
    360     name = ugettext_lazy(u'John Lennon')
    361     instrument = ugettext_lazy(u'guitar')
    362     result = string_concat([name, ': ', instrument])
    363 
    364 In this case, the lazy translations in ``result`` will only be converted to
    365 strings when ``result`` itself is used in a string (usually at template
    366 rendering time).
    367 
    368 The allow_lazy() decorator
    369 ~~~~~~~~~~~~~~~~~~~~~~~~~~
    370 
    371 Django offers many utility functions (particularly in ``django.utils``) that
    372 take a string as their first argument and do something to that string. These
    373 functions are used by template filters as well as directly in other code.
    374 
    375 If you write your own similar functions and deal with translations, you'll
    376 face the problem of what to do when the first argument is a lazy translation
    377 object. You don't want to convert it to a string immediately, because you might
    378 be using this function outside of a view (and hence the current thread's locale
    379 setting will not be correct).
    380 
    381 For cases like this, use the ``django.utils.functional.allow_lazy()``
    382 decorator. It modifies the function so that *if* it's called with a lazy
    383 translation as the first argument, the function evaluation is delayed until it
    384 needs to be converted to a string.
    385 
    386 For example::
    387 
    388     from django.utils.functional import allow_lazy
    389 
    390     def fancy_utility_function(s, ...):
    391         # Do some conversion on string 's'
    392         ...
    393     fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
    394 
    395 The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
    396 a number of extra arguments (``*args``) specifying the type(s) that the
    397 original function can return. Usually, it's enough to include ``unicode`` here
    398 and ensure that your function returns only Unicode strings.
    399 
    400 Using this decorator means you can write your function and assume that the
    401 input is a proper string, then add support for lazy translation objects at the
    402 end.
    403 
    404 .. _how-to-create-language-files:
    405 
    406 2. How to create language files
    407 ===============================
    408 
    409 Once you've tagged your strings for later translation, you need to write (or
    410 obtain) the language translations themselves. Here's how that works.
    411 
    412 .. admonition:: Locale restrictions
    413 
    414     Django does not support localizing your application into a locale for
    415     which Django itself has not been translated. In this case, it will ignore
    416     your translation files. If you were to try this and Django supported it,
    417     you would inevitably see a mixture of translated strings (from your
    418     application) and English strings (from Django itself). If you want to
    419     support a locale for your application that is not already part of
    420     Django, you'll need to make at least a minimal translation of the Django
    421     core. See the relevant :ref:`LocaleMiddleware note<locale-middleware-notes>`
    422     for more details.
    423 
    424 Message files
    425 -------------
    426 
    427 The first step is to create a **message file** for a new language. A message
    428 file is a plain-text file, representing a single language, that contains all
    429 available translation strings and how they should be represented in the given
    430 language. Message files have a ``.po`` file extension.
    431 
    432 Django comes with a tool, ``django-admin.py makemessages``, that automates the
    433 creation and upkeep of these files.
    434 
    435 .. admonition:: A note to Django veterans
    436 
    437     The old tool ``bin/make-messages.py`` has been moved to the command
    438     ``django-admin.py makemessages`` to provide consistency throughout Django.
    439 
    440 To create or update a message file, run this command::
    441 
    442     django-admin.py makemessages -l de
    443 
    444 ...where ``de`` is the language code for the message file you want to create.
    445 The language code, in this case, is in locale format. For example, it's
    446 ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German.
    447 
    448 The script should be run from one of three places:
    449 
    450     * The root directory of your Django project.
    451     * The root directory of your Django app.
    452     * The root ``django`` directory (not a Subversion checkout, but the one
    453       that is linked-to via ``$PYTHONPATH`` or is located somewhere on that
    454       path). This is only relevant when you are creating a translation for
    455       Django itself, see :ref:`contributing-translations`.
    456 
    457 Th script runs over your project source tree or your application source tree and
    458 pulls out all strings marked for translation. It creates (or updates) a message
    459 file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the
    460 file will be ``locale/de/LC_MESSAGES/django.po``.
    461 
    462 By default ``django-admin.py makemessages`` examines every file that has the
    463 ``.html`` file extension. In case you want to override that default, use the
    464 ``--extension`` or ``-e`` option to specify the file extensions to examine::
    465 
    466     django-admin.py makemessages -l de -e txt
    467 
    468 Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
    469 multiple times::
    470 
    471     django-admin.py makemessages -l=de -e=html,txt -e xml
    472 
    473 When `creating JavaScript translation catalogs`_ you need to use the special
    474 'djangojs' domain, **not** ``-e js``.
    475 
    476 .. _create a JavaScript translation catalog: `Creating JavaScript translation catalogs`_
    477 
    478 .. admonition:: No gettext?
    479 
    480     If you don't have the ``gettext`` utilities installed, ``django-admin.py
    481     makemessages`` will create empty files. If that's the case, either install
    482     the ``gettext`` utilities or just copy the English message file
    483     (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
    484     point; it's just an empty translation file.
    485 
    486 .. admonition:: Working on Windows?
    487 
    488    If you're using Windows and need to install the GNU gettext utilities so
    489    ``django-admin makemessages`` works see `gettext on Windows`_ for more
    490    information.
    491 
    492 The format of ``.po`` files is straightforward. Each ``.po`` file contains a
    493 small bit of metadata, such as the translation maintainer's contact
    494 information, but the bulk of the file is a list of **messages** -- simple
    495 mappings between translation strings and the actual translated text for the
    496 particular language.
    497 
    498 For example, if your Django app contained a translation string for the text
    499 ``"Welcome to my site."``, like so::
    500 
    501     _("Welcome to my site.")
    502 
    503 ...then ``django-admin.py makemessages`` will have created a ``.po`` file
    504 containing the following snippet -- a message::
    505 
    506     #: path/to/python/module.py:23
    507     msgid "Welcome to my site."
    508     msgstr ""
    509 
    510 A quick explanation:
    511 
    512     * ``msgid`` is the translation string, which appears in the source. Don't
    513       change it.
    514     * ``msgstr`` is where you put the language-specific translation. It starts
    515       out empty, so it's your responsibility to change it. Make sure you keep
    516       the quotes around your translation.
    517     * As a convenience, each message includes, in the form of a comment line
    518       prefixed with ``#`` and located above the ``msgid`` line, the filename and
    519       line number from which the translation string was gleaned.
    520 
    521 Long messages are a special case. There, the first string directly after the
    522 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
    523 written over the next few lines as one string per line. Those strings are
    524 directly concatenated. Don't forget trailing spaces within the strings;
    525 otherwise, they'll be tacked together without whitespace!
    526 
    527 .. admonition:: Mind your charset
    528 
    529     When creating a PO file with your favorite text editor, first edit
    530     the charset line (search for ``"CHARSET"``) and set it to the charset
    531     you'll be using to edit the content. Due to the way the ``gettext`` tools
    532     work internally and because we want to allow non-ASCII source strings in
    533     Django's core and your applications, you **must** use UTF-8 as the encoding
    534     for your PO file. This means that everybody will be using the same
    535     encoding, which is important when Django processes the PO files.
    536 
    537 To reexamine all source code and templates for new translation strings and
    538 update all message files for **all** languages, run this::
    539 
    540     django-admin.py makemessages -a
    541 
    542 Compiling message files
    543 -----------------------
    544 
    545 After you create your message file -- and each time you make changes to it --
    546 you'll need to compile it into a more efficient form, for use by ``gettext``.
    547 Do this with the ``django-admin.py compilemessages`` utility.
    548 
    549 This tool runs over all available ``.po`` files and creates ``.mo`` files, which
    550 are binary files optimized for use by ``gettext``. In the same directory from
    551 which you ran ``django-admin.py makemessages``, run ``django-admin.py
    552 compilemessages`` like this::
    553 
    554    django-admin.py compilemessages
    555 
    556 That's it. Your translations are ready for use.
    557 
    558 .. admonition:: A note to Django veterans
    559 
    560     The old tool ``bin/compile-messages.py`` has been moved to the command
    561     ``django-admin.py compilemessages`` to provide consistency throughout
    562     Django.
    563 
    564 .. admonition:: Working on Windows?
    565 
    566    If you're using Windows and need to install the GNU gettext utilities so
    567    ``django-admin compilemessages`` works see `gettext on Windows`_ for more
    568    information.
    569 
    570 .. _how-django-discovers-language-preference:
    571 
    572 3. How Django discovers language preference
    573 ===========================================
    574 
    575 Once you've prepared your translations -- or, if you just want to use the
    576 translations that come with Django -- you'll just need to activate translation
    577 for your app.
    578 
    579 Behind the scenes, Django has a very flexible model of deciding which language
    580 should be used -- installation-wide, for a particular user, or both.
    581 
    582 To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
    583 Django uses this language as the default translation -- the final attempt if no
    584 other translator finds a translation.
    585 
    586 If all you want to do is run Django with your native language, and a language
    587 file is available for your language, all you need to do is set
    588 ``LANGUAGE_CODE``.
    589 
    590 If you want to let each individual user specify which language he or she
    591 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
    592 selection based on data from the request. It customizes content for each user.
    593 
    594 To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
    595 to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you
    596 should follow these guidelines:
    597 
    598     * Make sure it's one of the first middlewares installed.
    599     * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
    600       makes use of session data.
    601     * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
    602 
    603 For example, your ``MIDDLEWARE_CLASSES`` might look like this::
    604 
    605     MIDDLEWARE_CLASSES = (
    606        'django.contrib.sessions.middleware.SessionMiddleware',
    607        'django.middleware.locale.LocaleMiddleware',
    608        'django.middleware.common.CommonMiddleware',
    609     )
    610 
    611 (For more on middleware, see the :ref:`middleware documentation
    612 <topics-http-middleware>`.)
    613 
    614 ``LocaleMiddleware`` tries to determine the user's language preference by
    615 following this algorithm:
    616 
    617     * First, it looks for a ``django_language`` key in the current user's
    618       session.
    619 
    620     * Failing that, it looks for a cookie.
    621 
    622       .. versionchanged:: 1.0
    623 
    624       In Django version 0.96 and before, the cookie's name is hard-coded to
    625       ``django_language``. In Django 1,0, The cookie name is set by the
    626       ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
    627       ``django_language``.)
    628 
    629     * Failing that, it looks at the ``Accept-Language`` HTTP header. This
    630       header is sent by your browser and tells the server which language(s) you
    631       prefer, in order by priority. Django tries each language in the header
    632       until it finds one with available translations.
    633 
    634     * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
    635 
    636 .. _locale-middleware-notes:
    637 
    638 Notes:
    639 
    640     * In each of these places, the language preference is expected to be in the
    641       standard language format, as a string. For example, Brazilian Portuguese
    642       is ``pt-br``.
    643 
    644     * If a base language is available but the sublanguage specified is not,
    645       Django uses the base language. For example, if a user specifies ``de-at``
    646       (Austrian German) but Django only has ``de`` available, Django uses
    647       ``de``.
    648 
    649     * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
    650       If you want to restrict the language selection to a subset of provided
    651       languages (because your application doesn't provide all those languages),
    652       set ``LANGUAGES`` to a list of languages. For example::
    653 
    654           LANGUAGES = (
    655             ('de', _('German')),
    656             ('en', _('English')),
    657           )
    658 
    659       This example restricts languages that are available for automatic
    660       selection to German and English (and any sublanguage, like de-ch or
    661       en-us).
    662 
    663       .. _LANGUAGES setting: ../settings/#languages
    664 
    665     * If you define a custom ``LANGUAGES`` setting, as explained in the
    666       previous bullet, it's OK to mark the languages as translation strings
    667       -- but use a "dummy" ``ugettext()`` function, not the one in
    668       ``django.utils.translation``. You should *never* import
    669       ``django.utils.translation`` from within your settings file, because that
    670       module in itself depends on the settings, and that would cause a circular
    671       import.
    672 
    673       The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
    674       settings file::
    675 
    676           ugettext = lambda s: s
    677 
    678           LANGUAGES = (
    679               ('de', ugettext('German')),
    680               ('en', ugettext('English')),
    681           )
    682 
    683       With this arrangement, ``django-admin.py makemessages`` will still find
    684       and mark these strings for translation, but the translation won't happen
    685       at runtime -- so you'll have to remember to wrap the languages in the
    686       *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
    687 
    688     * The ``LocaleMiddleware`` can only select languages for which there is a
    689       Django-provided base translation. If you want to provide translations
    690       for your application that aren't already in the set of translations
    691       in Django's source tree, you'll want to provide at least basic
    692       translations for that language. For example, Django uses technical
    693       message IDs to translate date formats and time formats -- so you will
    694       need at least those translations for the system to work correctly.
    695 
    696       A good starting point is to copy the English ``.po`` file and to
    697       translate at least the technical messages -- maybe the validation
    698       messages, too.
    699 
    700       Technical message IDs are easily recognized; they're all upper case. You
    701       don't translate the message ID as with other messages, you provide the
    702       correct local variant on the provided English value. For example, with
    703       ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would
    704       be the format string that you want to use in your language. The format
    705       is identical to the format strings used by the ``now`` template tag.
    706 
    707 Once ``LocaleMiddleware`` determines the user's preference, it makes this
    708 preference available as ``request.LANGUAGE_CODE`` for each
    709 :class:`~django.http.HttpRequest`. Feel free to read this value in your view
    710 code. Here's a simple example::
    711 
    712     def hello_world(request, count):
    713         if request.LANGUAGE_CODE == 'de-at':
    714             return HttpResponse("You prefer to read Austrian German.")
    715         else:
    716             return HttpResponse("You prefer to read another language.")
    717 
    718 Note that, with static (middleware-less) translation, the language is in
    719 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
    720 in ``request.LANGUAGE_CODE``.
    721 
    722 .. _settings file: ../settings/
    723 .. _middleware documentation: ../middleware/
    724 .. _session: ../sessions/
    725 .. _request object: ../request_response/#httprequest-objects
    726 
    727 .. _translations-in-your-own-projects:
    728 
    729 Using translations in your own projects
    730 =======================================
    731 
    732 Django looks for translations by following this algorithm:
    733 
    734     * First, it looks for a ``locale`` directory in the application directory
    735       of the view that's being called. If it finds a translation for the
    736       selected language, the translation will be installed.
    737     * Next, it looks for a ``locale`` directory in the project directory. If it
    738       finds a translation, the translation will be installed.
    739     * Finally, it checks the Django-provided base translation in
    740       ``django/conf/locale``.
    741 
    742 This way, you can write applications that include their own translations, and
    743 you can override base translations in your project path. Or, you can just build
    744 a big project out of several apps and put all translations into one big project
    745 message file. The choice is yours.
    746 
    747 .. note::
    748 
    749     If you're using manually configured settings, as described
    750     :ref:`settings-without-django-settings-module`, the ``locale`` directory in
    751     the project directory will not be examined, since Django loses the ability
    752     to work out the location of the project directory. (Django normally uses the
    753     location of the settings file to determine this, and a settings file doesn't
    754     exist if you're manually configuring your settings.)
    755 
    756 All message file repositories are structured the same way. They are:
    757 
    758     * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
    759     * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
    760     * All paths listed in ``LOCALE_PATHS`` in your settings file are
    761       searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
    762     * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
    763 
    764 To create message files, you use the same ``django-admin.py makemessages``
    765 tool as with the Django message files. You only need to be in the right place
    766 -- in the directory where either the ``conf/locale`` (in case of the source
    767 tree) or the ``locale/`` (in case of app messages or project messages)
    768 directory are located. And you use the same ``django-admin.py compilemessages``
    769 to produce the binary ``django.mo`` files that are used by ``gettext``.
    770 
    771 You can also run ``django-admin.py compilemessages --settings=path.to.settings``
    772 to make the compiler process all the directories in your ``LOCALE_PATHS``
    773 setting.
    774 
    775 Application message files are a bit complicated to discover -- they need the
    776 ``LocaleMiddleware``. If you don't use the middleware, only the Django message
    777 files and project message files will be processed.
    778 
    779 Finally, you should give some thought to the structure of your translation
    780 files. If your applications need to be delivered to other users and will
    781 be used in other projects, you might want to use app-specific translations.
    782 But using app-specific translations and project translations could produce
    783 weird problems with ``makemessages``: ``makemessages`` will traverse all
    784 directories below the current path and so might put message IDs into the
    785 project message file that are already in application message files.
    786 
    787 The easiest way out is to store applications that are not part of the project
    788 (and so carry their own translations) outside the project tree. That way,
    789 ``django-admin.py makemessages`` on the project level will only translate
    790 strings that are connected to your explicit project and not strings that are
    791 distributed independently.
    792 
    793 The ``set_language`` redirect view
    794 ==================================
    795 
    796 As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
    797 that sets a user's language preference and redirects back to the previous page.
    798 
    799 Activate this view by adding the following line to your URLconf::
    800 
    801     (r'^i18n/', include('django.conf.urls.i18n')),
    802 
    803 (Note that this example makes the view available at ``/i18n/setlang/``.)
    804 
    805 The view expects to be called via the ``POST`` method, with a ``language``
    806 parameter set in request. If session support is enabled, the view
    807 saves the language choice in the user's session. Otherwise, it saves the
    808 language choice in a cookie that is by default named ``django_language``.
    809 (The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
    810 
    811 After setting the language choice, Django redirects the user, following this
    812 algorithm:
    813 
    814     * Django looks for a ``next`` parameter in the ``POST`` data.
    815     * If that doesn't exist, or is empty, Django tries the URL in the
    816       ``Referrer`` header.
    817     * If that's empty -- say, if a user's browser suppresses that header --
    818       then the user will be redirected to ``/`` (the site root) as a fallback.
    819 
    820 Here's example HTML template code:
    821 
    822 .. code-block:: html+django
    823 
    824     <form action="/i18n/setlang/" method="post">
    825     <input name="next" type="hidden" value="/next/page/" />
    826     <select name="language">
    827     {% for lang in LANGUAGES %}
    828     <option value="{{ lang.0 }}">{{ lang.1 }}</option>
    829     {% endfor %}
    830     </select>
    831     <input type="submit" value="Go" />
    832     </form>
    833 
    834 Translations and JavaScript
    835 ===========================
    836 
    837 Adding translations to JavaScript poses some problems:
    838 
    839     * JavaScript code doesn't have access to a ``gettext`` implementation.
    840 
    841     * JavaScript code doesn't have access to .po or .mo files; they need to be
    842       delivered by the server.
    843 
    844     * The translation catalogs for JavaScript should be kept as small as
    845       possible.
    846 
    847 Django provides an integrated solution for these problems: It passes the
    848 translations into JavaScript, so you can call ``gettext``, etc., from within
    849 JavaScript.
    850 
    851 The ``javascript_catalog`` view
    852 -------------------------------
    853 
    854 The main solution to these problems is the ``javascript_catalog`` view, which
    855 sends out a JavaScript code library with functions that mimic the ``gettext``
    856 interface, plus an array of translation strings. Those translation strings are
    857 taken from the application, project or Django core, according to what you
    858 specify in either the info_dict or the URL.
    859 
    860 You hook it up like this::
    861 
    862     js_info_dict = {
    863         'packages': ('your.app.package',),
    864     }
    865 
    866     urlpatterns = patterns('',
    867         (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
    868     )
    869 
    870 Each string in ``packages`` should be in Python dotted-package syntax (the
    871 same format as the strings in ``INSTALLED_APPS``) and should refer to a package
    872 that contains a ``locale`` directory. If you specify multiple packages, all
    873 those catalogs are merged into one catalog. This is useful if you have
    874 JavaScript that uses strings from different applications.
    875 
    876 You can make the view dynamic by putting the packages into the URL pattern::
    877 
    878     urlpatterns = patterns('',
    879         (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
    880     )
    881 
    882 With this, you specify the packages as a list of package names delimited by '+'
    883 signs in the URL. This is especially useful if your pages use code from
    884 different apps and this changes often and you don't want to pull in one big
    885 catalog file. As a security measure, these values can only be either
    886 ``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
    887 
    888 Using the JavaScript translation catalog
    889 ----------------------------------------
    890 
    891 To use the catalog, just pull in the dynamically generated script like this::
    892 
    893     <script type="text/javascript" src="/path/to/jsi18n/"></script>
    894 
    895 This is how the admin fetches the translation catalog from the server. When the
    896 catalog is loaded, your JavaScript code can use the standard ``gettext``
    897 interface to access it::
    898 
    899     document.write(gettext('this is to be translated'));
    900 
    901 There is also an ``ngettext`` interface::
    902 
    903     var object_cnt = 1 // or 0, or 2, or 3, ...
    904     s = ngettext('literal for the singular case',
    905             'literal for the plural case', object_cnt);
    906 
    907 and even a string interpolation function::
    908 
    909     function interpolate(fmt, obj, named);
    910 
    911 The interpolation syntax is borrowed from Python, so the ``interpolate``
    912 function supports both positional and named interpolation:
    913 
    914     * Positional interpolation: ``obj`` contains a JavaScript Array object
    915       whose elements values are then sequentially interpolated in their
    916       corresponding ``fmt`` placeholders in the same order they appear.
    917       For example::
    918 
    919         fmts = ngettext('There is %s object. Remaining: %s',
    920                 'There are %s objects. Remaining: %s', 11);
    921         s = interpolate(fmts, [11, 20]);
    922         // s is 'There are 11 objects. Remaining: 20'
    923 
    924     * Named interpolation: This mode is selected by passing the optional
    925       boolean ``named`` parameter as true. ``obj`` contains a JavaScript
    926       object or associative array. For example::
    927 
    928         d = {
    929             count: 10
    930             total: 50
    931         };
    932 
    933         fmts = ngettext('Total: %(total)s, there is %(count)s object',
    934         'there are %(count)s of a total of %(total)s objects', d.count);
    935         s = interpolate(fmts, d, true);
    936 
    937 You shouldn't go over the top with string interpolation, though: this is still
    938 JavaScript, so the code has to make repeated regular-expression substitutions.
    939 This isn't as fast as string interpolation in Python, so keep it to those
    940 cases where you really need it (for example, in conjunction with ``ngettext``
    941 to produce proper pluralizations).
    942 
    943 Creating JavaScript translation catalogs
    944 ----------------------------------------
    945 
    946 You create and update the translation catalogs the same way as the other
    947 
    948 Django translation catalogs -- with the django-admin.py makemessages tool. The
    949 only difference is you need to provide a ``-d djangojs`` parameter, like this::
    950 
    951     django-admin.py makemessages -d djangojs -l de
    952 
    953 This would create or update the translation catalog for JavaScript for German.
    954 After updating translation catalogs, just run ``django-admin.py compilemessages``
    955 the same way as you do with normal Django translation catalogs.
    956 
    957 Specialties of Django translation
    958 ==================================
    959 
    960 If you know ``gettext``, you might note these specialties in the way Django
    961 does translation:
    962 
    963     * The string domain is ``django`` or ``djangojs``. This string domain is
    964       used to differentiate between different programs that store their data
    965       in a common message-file library (usually ``/usr/share/locale/``). The
    966       ``django`` domain is used for python and template translation strings
    967       and is loaded into the global translation catalogs. The ``djangojs``
    968       domain is only used for JavaScript translation catalogs to make sure
    969       that those are as small as possible.
    970     * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
    971       ``xgettext`` and ``msgfmt``. This is mostly for convenience.
    972 
    973 ``gettext`` on Windows
    974 ======================
    975 
    976 This is only needed for people who either want to extract message IDs or compile
    977 message files (``.po``). Translation work itself just involves editing existing
    978 files of this type, but if you want to create your own message files, or want to
    979 test or compile a changed message file, you will need the ``gettext`` utilities:
    980 
    981     * Download the following zip files from
    982       http://sourceforge.net/projects/gettext
    983 
    984       * ``gettext-runtime-X.bin.woe32.zip``
    985       * ``gettext-tools-X.bin.woe32.zip``
    986       * ``libiconv-X.bin.woe32.zip``
    987 
    988     * Extract the 3 files in the same folder (i.e. ``C:\Program
    989       Files\gettext-utils``)
    990 
    991     * Update the system PATH:
    992 
    993       * ``Control Panel > System > Advanced > Environment Variables``
    994       * In the ``System variables`` list, click ``Path``, click ``Edit``
    995       * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
    996         ``Variable value`` field
    997 
    998 You may also use ``gettext`` binaries you have obtained elsewhere, so long as
    999 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries
    1000 have been found to not support this command. Do not attempt to use Django
    1001 translation utilities with a ``gettext`` package if the command ``xgettext
    1002 --version`` entered at a Windows command prompt causes a popup window saying
    1003 "xgettext.exe has generated errors and will be closed by Windows".
  • new file docs/topics/i18n/deployment.txt

    diff --git a/docs/topics/i18n/deployment.txt b/docs/topics/i18n/deployment.txt
    new file mode 100644
    - +  
     1.. _topics-i18n-deployment:
     2
     3=============================================
     4Deployment of Django application translations
     5=============================================
     6
     7If you don't need internationalization in your app
     8==================================================
     9
     10Django's internationalization hooks are on by default, and that means there's a
     11bit of i18n-related overhead in certain places of the framework. If you don't
     12use internationalization, you should take the two seconds to set
     13:setting:`USE_I18N = False <USE_I18N>` in your settings file. If
     14:setting:`USE_I18N` is set to ``False``, then Django will make some
     15optimizations so as not to load the internationalization machinery.
     16
     17You'll probably also want to remove ``'django.core.context_processors.i18n'``
     18from your ``TEMPLATE_CONTEXT_PROCESSORS`` setting.
     19
     20If you do need internationalization
     21===================================
     22
     23.. _how-django-discovers-language-preference:
     24
     25How Django discovers language preference
     26----------------------------------------
     27
     28Once you've prepared your translations -- or, if you just want to use the
     29translations that come with Django -- you'll just need to activate translation
     30for your app.
     31
     32Behind the scenes, Django has a very flexible model of deciding which language
     33should be used -- installation-wide, for a particular user, or both.
     34
     35To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
     36Django uses this language as the default translation -- the final attempt if no
     37other translator finds a translation.
     38
     39If all you want to do is run Django with your native language, and a language
     40file is available for it, all you need to do is set ``LANGUAGE_CODE``.
     41
     42If you want to let each individual user specify which language he or she
     43prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
     44selection based on data from the request. It customizes content for each user.
     45
     46To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
     47to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you
     48should follow these guidelines:
     49
     50    * Make sure it's one of the first middlewares installed.
     51    * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
     52      makes use of session data.
     53    * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
     54
     55For example, your ``MIDDLEWARE_CLASSES`` might look like this::
     56
     57    MIDDLEWARE_CLASSES = (
     58       'django.contrib.sessions.middleware.SessionMiddleware',
     59       'django.middleware.locale.LocaleMiddleware',
     60       'django.middleware.common.CommonMiddleware',
     61    )
     62
     63(For more on middleware, see the :ref:`middleware documentation
     64<topics-http-middleware>`.)
     65
     66``LocaleMiddleware`` tries to determine the user's language preference by
     67following this algorithm:
     68
     69    * First, it looks for a ``django_language`` key in the current user's
     70      session.
     71
     72    * Failing that, it looks for a cookie.
     73
     74      .. versionchanged:: 1.0
     75
     76      In Django version 0.96 and before, the cookie's name is hard-coded to
     77      ``django_language``. In Django 1,0, The cookie name is set by the
     78      ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
     79      ``django_language``.)
     80
     81    * Failing that, it looks at the ``Accept-Language`` HTTP header. This
     82      header is sent by your browser and tells the server which language(s) you
     83      prefer, in order by priority. Django tries each language in the header
     84      until it finds one with available translations.
     85
     86    * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
     87
     88.. _locale-middleware-notes:
     89
     90Notes:
     91
     92    * In each of these places, the language preference is expected to be in the
     93      standard language format, as a string. For example, Brazilian Portuguese
     94      is ``pt-br``.
     95
     96    * If a base language is available but the sublanguage specified is not,
     97      Django uses the base language. For example, if a user specifies ``de-at``
     98      (Austrian German) but Django only has ``de`` available, Django uses
     99      ``de``.
     100
     101    * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
     102      If you want to restrict the language selection to a subset of provided
     103      languages (because your application doesn't provide all those languages),
     104      set ``LANGUAGES`` to a list of languages. For example::
     105
     106          LANGUAGES = (
     107            ('de', _('German')),
     108            ('en', _('English')),
     109          )
     110
     111      This example restricts languages that are available for automatic
     112      selection to German and English (and any sublanguage, like de-ch or
     113      en-us).
     114
     115      .. _LANGUAGES setting: ../settings/#languages
     116
     117    * If you define a custom ``LANGUAGES`` setting, as explained in the
     118      previous bullet, it's OK to mark the languages as translation strings
     119      -- but use a "dummy" ``ugettext()`` function, not the one in
     120      ``django.utils.translation``. You should *never* import
     121      ``django.utils.translation`` from within your settings file, because that
     122      module in itself depends on the settings, and that would cause a circular
     123      import.
     124
     125      The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
     126      settings file::
     127
     128          ugettext = lambda s: s
     129
     130          LANGUAGES = (
     131              ('de', ugettext('German')),
     132              ('en', ugettext('English')),
     133          )
     134
     135      With this arrangement, ``django-admin.py makemessages`` will still find
     136      and mark these strings for translation, but the translation won't happen
     137      at runtime -- so you'll have to remember to wrap the languages in the
     138      *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
     139
     140    * The ``LocaleMiddleware`` can only select languages for which there is a
     141      Django-provided base translation. If you want to provide translations
     142      for your application that aren't already in the set of translations
     143      in Django's source tree, you'll want to provide at least a basic
     144      one as described in the :ref:`Locale restrictions<locale-restrictions>`
     145      note.
     146
     147Once ``LocaleMiddleware`` determines the user's preference, it makes this
     148preference available as ``request.LANGUAGE_CODE`` for each
     149:class:`~django.http.HttpRequest`. Feel free to read this value in your view
     150code. Here's a simple example::
     151
     152    def hello_world(request, count):
     153        if request.LANGUAGE_CODE == 'de-at':
     154            return HttpResponse("You prefer to read Austrian German.")
     155        else:
     156            return HttpResponse("You prefer to read another language.")
     157
     158Note that, with static (middleware-less) translation, the language is in
     159``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
     160in ``request.LANGUAGE_CODE``.
     161
     162.. _settings file: ../settings/
     163.. _middleware documentation: ../middleware/
     164.. _session: ../sessions/
     165.. _request object: ../request_response/#httprequest-objects
     166
  • new file docs/topics/i18n/index.txt

    diff --git a/docs/topics/i18n/index.txt b/docs/topics/i18n/index.txt
    new file mode 100644
    - +  
     1.. _topics-i18n:
     2
     3=====================================
     4Internationalization and localization
     5=====================================
     6
     7Overview
     8========
     9
     10Django has full support for internationalization of text in code and templates.
     11
     12Essentially, Django does two things:
     13
     14    * It lets developers and template authors specify which parts of their apps
     15      should be translatable.
     16    * It uses these hooks to translate Web apps for particular users according
     17      to their language preferences.
     18
     19The complete process can be seen as divided in three stages. It is also possible
     20to identify an identical number of roles with very well defined responsabilities
     21associated with each of these tasks (although it's perfectly normal if you
     22find yourself performing more than one of these roles):
     23
     24    * For applicacion authors wishing to make sure their Django apps can be
     25      used in different locales: Internationalization.
     26    * For translators wanting to translate Django apps: Localization.
     27    * For system administrators/final users setting up internationalized apps or
     28      developers integrating third party apps: Deployment.
     29
     30.. toctree::
     31   :maxdepth: 1
     32
     33   internationalization
     34   localization
     35   deployment
     36
     37.. _ seealso::
     38
     39For more general information about the topic, see the `GNU gettext documentation`_
     40and the `Wikipedia article`_
     41
     42.. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts
     43.. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization
     44
     45Specialties of Django translation
     46==================================
     47
     48Django's translation machinery uses the standard ``gettext`` module that comes
     49with Python.  If you know ``gettext``, you might note these specialties in the
     50way Django does translation:
     51
     52    * The string domain is ``django`` or ``djangojs``. This string domain is
     53      used to differentiate between different programs that store their data
     54      in a common message-file library (usually ``/usr/share/locale/``). The
     55      ``django`` domain is used for python and template translation strings
     56      and is loaded into the global translation catalogs. The ``djangojs``
     57      domain is only used for JavaScript translation catalogs to make sure
     58      that those are as small as possible.
     59    * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
     60      ``xgettext`` and ``msgfmt``. This is mostly for convenience.
  • new file docs/topics/i18n/internationalization.txt

    diff --git a/docs/topics/i18n/internationalization.txt b/docs/topics/i18n/internationalization.txt
    new file mode 100644
    - +  
     1.. _topics-i18n-internationalization:
     2
     3====================
     4Internationalization
     5====================
     6
     7Overview
     8========
     9
     10The goal of internationalization is to allow a single Web application to offer
     11its content and functionality in multiple languages.
     12
     13You, the Django developer, can accomplish this goal by adding a minimal amount
     14of hooks to your Python (and JavaScript) code and templates. These hooks are
     15called **translation strings**. They tell Django: "This text should be
     16translated into the end user's language, if a translation for this text is
     17available in that language." . It's your responsibility to mark translatable
     18strings; the system can only translate strings it knows about.
     19
     20Django takes care of using these hooks to translate Web apps, on the fly,
     21according to users' language preferences.
     22
     23Specifying translation strings: In Python code
     24==============================================
     25
     26Standard translation
     27--------------------
     28
     29Specify a translation string by using the function ``ugettext()``. It's
     30convention to import this as a shorter alias, ``_``, to save typing.
     31
     32.. note::
     33    Python's standard library ``gettext`` module installs ``_()`` into the
     34    global namespace, as an alias for ``gettext()``. In Django, we have chosen
     35    not to follow this practice, for a couple of reasons:
     36
     37      1. For international character set (Unicode) support, ``ugettext()`` is
     38         more useful than ``gettext()``. Sometimes, you should be using
     39         ``ugettext_lazy()`` as the default translation method for a particular
     40         file. Without ``_()`` in the global namespace, the developer has to
     41         think about which is the most appropriate translation function.
     42
     43      2. The underscore character (``_``) is used to represent "the previous
     44         result" in Python's interactive shell and doctest tests. Installing a
     45         global ``_()`` function causes interference. Explicitly importing
     46         ``ugettext()`` as ``_()`` avoids this problem.
     47
     48.. highlightlang:: python
     49
     50In this example, the text ``"Welcome to my site."`` is marked as a translation
     51string::
     52
     53    from django.utils.translation import ugettext as _
     54
     55    def my_view(request):
     56        output = _("Welcome to my site.")
     57        return HttpResponse(output)
     58
     59Obviously, you could code this without using the alias. This example is
     60identical to the previous one::
     61
     62    from django.utils.translation import ugettext
     63
     64    def my_view(request):
     65        output = ugettext("Welcome to my site.")
     66        return HttpResponse(output)
     67
     68Translation works on computed values. This example is identical to the previous
     69two::
     70
     71    def my_view(request):
     72        words = ['Welcome', 'to', 'my', 'site.']
     73        output = _(' '.join(words))
     74        return HttpResponse(output)
     75
     76Translation works on variables. Again, here's an identical example::
     77
     78    def my_view(request):
     79        sentence = 'Welcome to my site.'
     80        output = _(sentence)
     81        return HttpResponse(output)
     82
     83(The caveat with using variables or computed values, as in the previous two
     84examples, is that Django's translation-string-detecting utility,
     85``django-admin.py makemessages``, won't be able to find these strings. More on
     86``makemessages`` later.)
     87
     88The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
     89specified with Python's standard named-string interpolation syntax. Example::
     90
     91    def my_view(request, m, d):
     92        output = _('Today is %(month)s, %(day)s.') % {'month': m, 'day': d}
     93        return HttpResponse(output)
     94
     95This technique lets language-specific translations reorder the placeholder
     96text. For example, an English translation may be ``"Today is November, 26."``,
     97while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
     98placeholders (the month and the day) with their positions swapped.
     99
     100For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
     101instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
     102have more than a single parameter. If you used positional interpolation,
     103translations wouldn't be able to reorder placeholder text.
     104
     105Marking strings as no-op
     106------------------------
     107
     108Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
     109as a translation string without translating it. The string is later translated
     110from a variable.
     111
     112Use this if you have constant strings that should be stored in the source
     113language because they are exchanged over systems or users -- such as strings in
     114a database -- but should be translated at the last possible point in time, such
     115as when the string is presented to the user.
     116
     117Pluralization
     118-------------
     119
     120Use the function ``django.utils.translation.ungettext()`` to specify pluralized
     121messages. Example::
     122
     123    from django.utils.translation import ungettext
     124    def hello_world(request, count):
     125        page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
     126            'count': count,
     127        }
     128        return HttpResponse(page)
     129
     130``ungettext`` takes three arguments: the singular translation string, the plural
     131translation string and the number of objects (which is passed to the
     132translation languages as the ``count`` variable).
     133
     134.. _lazy-translations:
     135
     136Lazy translation
     137----------------
     138
     139Use the function ``django.utils.translation.ugettext_lazy()`` to translate
     140strings lazily -- when the value is accessed rather than when the
     141``ugettext_lazy()`` function is called.
     142
     143For example, to translate a model's ``help_text``, do the following::
     144
     145    from django.utils.translation import ugettext_lazy
     146
     147    class MyThing(models.Model):
     148        name = models.CharField(help_text=ugettext_lazy('This is the help text'))
     149
     150In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
     151not the actual translation. The translation itself will be done when the string
     152is used in a string context, such as template rendering on the Django admin
     153site.
     154
     155The result of a ``ugettext_lazy()`` call can be used wherever you would use a
     156unicode string (an object with type ``unicode``) in Python. If you try to use
     157it where a bytestring (a ``str`` object) is expected, things will not work as
     158expected, since a ``ugettext_lazy()`` object doesn't know how to convert
     159itself to a bytestring.  You can't use a unicode string inside a bytestring,
     160either, so this is consistent with normal Python behavior. For example::
     161
     162    # This is fine: putting a unicode proxy into a unicode string.
     163    u"Hello %s" % ugettext_lazy("people")
     164
     165    # This will not work, since you cannot insert a unicode object
     166    # into a bytestring (nor can you insert our unicode proxy there)
     167    "Hello %s" % ugettext_lazy("people")
     168
     169If you ever see output that looks like ``"hello
     170<django.utils.functional...>"``, you have tried to insert the result of
     171``ugettext_lazy()`` into a bytestring. That's a bug in your code.
     172
     173If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
     174``_`` (underscore), like so::
     175
     176    from django.utils.translation import ugettext_lazy as _
     177
     178    class MyThing(models.Model):
     179        name = models.CharField(help_text=_('This is the help text'))
     180
     181Always use lazy translations in :ref:`Django models <topics-db-models>`.
     182Field names and table names should be marked for translation (otherwise, they
     183won't be translated in the admin interface). This means writing explicit
     184``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,
     185though, rather than relying on Django's default determination of
     186``verbose_name`` and ``verbose_name_plural`` by looking at the model's class
     187name::
     188
     189    from django.utils.translation import ugettext_lazy as _
     190
     191    class MyThing(models.Model):
     192        name = models.CharField(_('name'), help_text=_('This is the help text'))
     193        class Meta:
     194            verbose_name = _('my thing')
     195            verbose_name_plural = _('mythings')
     196
     197Working with lazy translation objects
     198-------------------------------------
     199
     200.. highlightlang:: python
     201
     202Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
     203and utility functions is a common operation. When you're working with these
     204objects elsewhere in your code, you should ensure that you don't accidentally
     205convert them to strings, because they should be converted as late as possible
     206(so that the correct locale is in effect). This necessitates the use of a
     207couple of helper functions.
     208
     209Joining strings: string_concat()
     210~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     211
     212Standard Python string joins (``''.join([...])``) will not work on lists
     213containing lazy translation objects. Instead, you can use
     214``django.utils.translation.string_concat()``, which creates a lazy object that
     215concatenates its contents *and* converts them to strings only when the result
     216is included in a string. For example::
     217
     218    from django.utils.translation import string_concat
     219    ...
     220    name = ugettext_lazy(u'John Lennon')
     221    instrument = ugettext_lazy(u'guitar')
     222    result = string_concat([name, ': ', instrument])
     223
     224In this case, the lazy translations in ``result`` will only be converted to
     225strings when ``result`` itself is used in a string (usually at template
     226rendering time).
     227
     228The allow_lazy() decorator
     229~~~~~~~~~~~~~~~~~~~~~~~~~~
     230
     231Django offers many utility functions (particularly in ``django.utils``) that
     232take a string as their first argument and do something to that string. These
     233functions are used by template filters as well as directly in other code.
     234
     235If you write your own similar functions and deal with translations, you'll
     236face the problem of what to do when the first argument is a lazy translation
     237object. You don't want to convert it to a string immediately, because you might
     238be using this function outside of a view (and hence the current thread's locale
     239setting will not be correct).
     240
     241For cases like this, use the ``django.utils.functional.allow_lazy()``
     242decorator. It modifies the function so that *if* it's called with a lazy
     243translation as the first argument, the function evaluation is delayed until it
     244needs to be converted to a string.
     245
     246For example::
     247
     248    from django.utils.functional import allow_lazy
     249
     250    def fancy_utility_function(s, ...):
     251        # Do some conversion on string 's'
     252        ...
     253    fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
     254
     255The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
     256a number of extra arguments (``*args``) specifying the type(s) that the
     257original function can return. Usually, it's enough to include ``unicode`` here
     258and ensure that your function returns only Unicode strings.
     259
     260Using this decorator means you can write your function and assume that the
     261input is a proper string, then add support for lazy translation objects at the
     262end.
     263
     264Specifying translation strings: In template code
     265================================================
     266
     267.. highlightlang:: html+django
     268
     269Translations in :ref:`Django templates <topics-templates>` uses two template
     270tags and a slightly different syntax than in Python code. To give your template
     271access to these tags, put ``{% load i18n %}`` toward the top of your template.
     272
     273The ``{% trans %}`` template tag translates either a constant string
     274(enclosed in single or double quotes) or variable content::
     275
     276    <title>{% trans "This is the title." %}</title>
     277    <title>{% trans myvar %}</title>
     278
     279If the ``noop`` option is present, variable lookup still takes place but the
     280translation is skipped. This is useful when "stubbing out" content that will
     281require translation in the future::
     282
     283    <title>{% trans "myvar" noop %}</title>
     284
     285It's not possible to mix a template variable inside a string within ``{% trans
     286%}``. If your translations require strings with variables (placeholders), use
     287``{% blocktrans %}``::
     288
     289    {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
     290
     291To translate a template expression -- say, using template filters -- you need
     292to bind the expression to a local variable for use within the translation
     293block::
     294
     295    {% blocktrans with value|filter as myvar %}
     296    This will have {{ myvar }} inside.
     297    {% endblocktrans %}
     298
     299If you need to bind more than one expression inside a ``blocktrans`` tag,
     300separate the pieces with ``and``::
     301
     302    {% blocktrans with book|title as book_t and author|title as author_t %}
     303    This is {{ book_t }} by {{ author_t }}
     304    {% endblocktrans %}
     305
     306To pluralize, specify both the singular and plural forms with the
     307``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and
     308``{% endblocktrans %}``. Example::
     309
     310    {% blocktrans count list|length as counter %}
     311    There is only one {{ name }} object.
     312    {% plural %}
     313    There are {{ counter }} {{ name }} objects.
     314    {% endblocktrans %}
     315
     316Internally, all block and inline translations use the appropriate
     317``ugettext`` / ``ungettext`` call.
     318
     319Each ``RequestContext`` has access to three translation-specific variables:
     320
     321    * ``LANGUAGES`` is a list of tuples in which the first element is the
     322      language code and the second is the language name (translated into the
     323      currently active locale).
     324
     325    * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
     326      Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`,
     327      below.)
     328
     329    * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
     330      right-to-left language, e.g.: Hebrew, Arabic. If False it's a
     331      left-to-right language, e.g.: English, French, German etc.
     332
     333
     334If you don't use the ``RequestContext`` extension, you can get those values with
     335three tags::
     336
     337    {% get_current_language as LANGUAGE_CODE %}
     338    {% get_available_languages as LANGUAGES %}
     339    {% get_current_language_bidi as LANGUAGE_BIDI %}
     340
     341These tags also require a ``{% load i18n %}``.
     342
     343Translation hooks are also available within any template block tag that accepts
     344constant strings. In those cases, just use ``_()`` syntax to specify a
     345translation string::
     346
     347    {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
     348
     349In this case, both the tag and the filter will see the already-translated
     350string, so they don't need to be aware of translations.
     351
     352.. note::
     353    In this example, the translation infrastructure will be passed the string
     354    ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
     355    translated string will need to contain the comma so that the filter
     356    parsing code knows how to split up the arguments. For example, a German
     357    translator might translate the string ``"yes,no"`` as ``"ja,nein"``
     358    (keeping the comma intact).
     359
     360.. _Django templates: ../templates_python/
     361
     362Specifying translation strings: In JavaScript code
     363==================================================
     364
     365Adding translations to JavaScript poses some problems:
     366
     367    * JavaScript code doesn't have access to a ``gettext`` implementation.
     368
     369    * JavaScript code doesn't have access to .po or .mo files; they need to be
     370      delivered by the server.
     371
     372    * The translation catalogs for JavaScript should be kept as small as
     373      possible.
     374
     375Django provides an integrated solution for these problems: It passes the
     376translations into JavaScript, so you can call ``gettext``, etc., from within
     377JavaScript.
     378
     379The ``javascript_catalog`` view
     380-------------------------------
     381
     382The main solution to these problems is the ``javascript_catalog`` view, which
     383sends out a JavaScript code library with functions that mimic the ``gettext``
     384interface, plus an array of translation strings. Those translation strings are
     385taken from the application, project or Django core, according to what you
     386specify in either the info_dict or the URL.
     387
     388You hook it up like this::
     389
     390    js_info_dict = {
     391        'packages': ('your.app.package',),
     392    }
     393
     394    urlpatterns = patterns('',
     395        (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
     396    )
     397
     398Each string in ``packages`` should be in Python dotted-package syntax (the
     399same format as the strings in ``INSTALLED_APPS``) and should refer to a package
     400that contains a ``locale`` directory. If you specify multiple packages, all
     401those catalogs are merged into one catalog. This is useful if you have
     402JavaScript that uses strings from different applications.
     403
     404You can make the view dynamic by putting the packages into the URL pattern::
     405
     406    urlpatterns = patterns('',
     407        (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
     408    )
     409
     410With this, you specify the packages as a list of package names delimited by '+'
     411signs in the URL. This is especially useful if your pages use code from
     412different apps and this changes often and you don't want to pull in one big
     413catalog file. As a security measure, these values can only be either
     414``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
     415
     416Using the JavaScript translation catalog
     417----------------------------------------
     418
     419To use the catalog, just pull in the dynamically generated script like this::
     420
     421    <script type="text/javascript" src="/path/to/jsi18n/"></script>
     422
     423This is how the admin fetches the translation catalog from the server. When the
     424catalog is loaded, your JavaScript code can use the standard ``gettext``
     425interface to access it::
     426
     427    document.write(gettext('this is to be translated'));
     428
     429There is also an ``ngettext`` interface::
     430
     431    var object_cnt = 1 // or 0, or 2, or 3, ...
     432    s = ngettext('literal for the singular case',
     433            'literal for the plural case', object_cnt);
     434
     435and even a string interpolation function::
     436
     437    function interpolate(fmt, obj, named);
     438
     439The interpolation syntax is borrowed from Python, so the ``interpolate``
     440function supports both positional and named interpolation:
     441
     442    * Positional interpolation: ``obj`` contains a JavaScript Array object
     443      whose elements values are then sequentially interpolated in their
     444      corresponding ``fmt`` placeholders in the same order they appear.
     445      For example::
     446
     447        fmts = ngettext('There is %s object. Remaining: %s',
     448                'There are %s objects. Remaining: %s', 11);
     449        s = interpolate(fmts, [11, 20]);
     450        // s is 'There are 11 objects. Remaining: 20'
     451
     452    * Named interpolation: This mode is selected by passing the optional
     453      boolean ``named`` parameter as true. ``obj`` contains a JavaScript
     454      object or associative array. For example::
     455
     456        d = {
     457            count: 10
     458            total: 50
     459        };
     460
     461        fmts = ngettext('Total: %(total)s, there is %(count)s object',
     462        'there are %(count)s of a total of %(total)s objects', d.count);
     463        s = interpolate(fmts, d, true);
     464
     465You shouldn't go over the top with string interpolation, though: this is still
     466JavaScript, so the code has to make repeated regular-expression substitutions.
     467This isn't as fast as string interpolation in Python, so keep it to those
     468cases where you really need it (for example, in conjunction with ``ngettext``
     469to produce proper pluralizations).
     470
     471The ``set_language`` redirect view
     472==================================
     473
     474As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
     475that sets a user's language preference and redirects back to the previous page.
     476
     477Activate this view by adding the following line to your URLconf::
     478
     479    (r'^i18n/', include('django.conf.urls.i18n')),
     480
     481(Note that this example makes the view available at ``/i18n/setlang/``.)
     482
     483The view expects to be called via the ``POST`` method, with a ``language``
     484parameter set in request. If session support is enabled, the view
     485saves the language choice in the user's session. Otherwise, it saves the
     486language choice in a cookie that is by default named ``django_language``.
     487(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
     488
     489After setting the language choice, Django redirects the user, following this
     490algorithm:
     491
     492    * Django looks for a ``next`` parameter in the ``POST`` data.
     493    * If that doesn't exist, or is empty, Django tries the URL in the
     494      ``Referrer`` header.
     495    * If that's empty -- say, if a user's browser suppresses that header --
     496      then the user will be redirected to ``/`` (the site root) as a fallback.
     497
     498Here's example HTML template code:
     499
     500.. code-block:: html+django
     501
     502    <form action="/i18n/setlang/" method="post">
     503    <input name="next" type="hidden" value="/next/page/" />
     504    <select name="language">
     505    {% for lang in LANGUAGES %}
     506    <option value="{{ lang.0 }}">{{ lang.1 }}</option>
     507    {% endfor %}
     508    </select>
     509    <input type="submit" value="Go" />
     510    </form>
  • new file docs/topics/i18n/localization.txt

    diff --git a/docs/topics/i18n/localization.txt b/docs/topics/i18n/localization.txt
    new file mode 100644
    - +  
     1.. _topics-i18n-localization:
     2
     3============
     4Localization
     5============
     6
     7.. _how-to-create-language-files:
     8
     9How to create language files
     10============================
     11
     12Once the string literals of an application have been tagged for later
     13translation, the translation themselves need to be written (or obtained). Here's
     14how that works.
     15
     16.. _locale-restrictions:
     17
     18.. admonition:: Locale restrictions
     19
     20    Django does not support localizing your application into a locale for which
     21    Django itself has not been translated. In this case, it will ignore your
     22    translation files. If you were to try this and Django supported it, you
     23    would inevitably see a mixture of translated strings (from your application)
     24    and English strings (from Django itself). If you want to support a locale
     25    for your application that is not already part of Django, you'll need to make
     26    at least a minimal translation of the Django core.
     27
     28    A good starting point is to copy the Django English ``.po`` file and to
     29    translate at least the :ref:`technical-messages` -- maybe the validation
     30    messages, too.
     31
     32Message files
     33-------------
     34
     35The first step is to create a **message file** for a new language. A message
     36file is a plain-text file, representing a single language, that contains all
     37available translation strings and how they should be represented in the given
     38language. Message files have a ``.po`` file extension.
     39
     40Django comes with a tool, ``django-admin.py makemessages``, that automates the
     41creation and upkeep of these files.
     42
     43.. admonition:: A note to Django veterans
     44
     45    The old tool ``bin/make-messages.py`` has been moved to the command
     46    ``django-admin.py makemessages`` to provide consistency throughout Django.
     47
     48To create or update a message file, run this command::
     49
     50    django-admin.py makemessages -l de
     51
     52...where ``de`` is the language code for the message file you want to create.
     53The language code, in this case, is in locale format. For example, it's
     54``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German.
     55
     56The script should be run from one of two places:
     57
     58    * The root directory of your Django project.
     59    * The root directory of your Django app.
     60
     61Th script runs over your project source tree or your application source tree and
     62pulls out all strings marked for translation. It creates (or updates) a message
     63file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the
     64file will be ``locale/de/LC_MESSAGES/django.po``.
     65
     66By default ``django-admin.py makemessages`` examines every file that has the
     67``.html`` file extension. In case you want to override that default, use the
     68``--extension`` or ``-e`` option to specify the file extensions to examine::
     69
     70    django-admin.py makemessages -l de -e txt
     71
     72Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
     73multiple times::
     74
     75    django-admin.py makemessages -l=de -e=html,txt -e xml
     76
     77When :ref:`creating message files from JavaScript source code
     78<creating-message-files-from-js-code>` you need to use the special 'djangojs'
     79domain, **not** ``-e js``.
     80
     81.. admonition:: No gettext?
     82
     83    If you don't have the ``gettext`` utilities installed, ``django-admin.py
     84    makemessages`` will create empty files. If that's the case, either install
     85    the ``gettext`` utilities or just copy the English message file
     86    (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
     87    point; it's just an empty translation file.
     88
     89.. admonition:: Working on Windows?
     90
     91   If you're using Windows and need to install the GNU gettext utilities so
     92   ``django-admin makemessages`` works see :ref:`gettext_on_windows` for more
     93   information.
     94
     95The format of ``.po`` files is straightforward. Each ``.po`` file contains a
     96small bit of metadata, such as the translation maintainer's contact
     97information, but the bulk of the file is a list of **messages** -- simple
     98mappings between translation strings and the actual translated text for the
     99particular language.
     100
     101For example, if your Django app contained a translation string for the text
     102``"Welcome to my site."``, like so::
     103
     104    _("Welcome to my site.")
     105
     106...then ``django-admin.py makemessages`` will have created a ``.po`` file
     107containing the following snippet -- a message::
     108
     109    #: path/to/python/module.py:23
     110    msgid "Welcome to my site."
     111    msgstr ""
     112
     113A quick explanation:
     114
     115    * ``msgid`` is the translation string, which appears in the source. Don't
     116      change it.
     117    * ``msgstr`` is where you put the language-specific translation. It starts
     118      out empty, so it's your responsibility to change it. Make sure you keep
     119      the quotes around your translation.
     120    * As a convenience, each message includes, in the form of a comment line
     121      prefixed with ``#`` and located above the ``msgid`` line, the filename and
     122      line number from which the translation string was gleaned.
     123
     124Long messages are a special case. There, the first string directly after the
     125``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
     126written over the next few lines as one string per line. Those strings are
     127directly concatenated. Don't forget trailing spaces within the strings;
     128otherwise, they'll be tacked together without whitespace!
     129
     130.. admonition:: Mind your charset
     131
     132    When creating a PO file with your favorite text editor, first edit
     133    the charset line (search for ``"CHARSET"``) and set it to the charset
     134    you'll be using to edit the content. Due to the way the ``gettext`` tools
     135    work internally and because we want to allow non-ASCII source strings in
     136    Django's core and your applications, you **must** use UTF-8 as the encoding
     137    for your PO file. This means that everybody will be using the same
     138    encoding, which is important when Django processes the PO files.
     139
     140To reexamine all source code and templates for new translation strings and
     141update all message files for **all** languages, run this::
     142
     143    django-admin.py makemessages -a
     144
     145Compiling message files
     146-----------------------
     147
     148After you create your message file -- and each time you make changes to it --
     149you'll need to compile it into a more efficient form, for use by ``gettext``.
     150Do this with the ``django-admin.py compilemessages`` utility.
     151
     152This tool runs over all available ``.po`` files and creates ``.mo`` files, which
     153are binary files optimized for use by ``gettext``. In the same directory from
     154which you ran ``django-admin.py makemessages``, run ``django-admin.py
     155compilemessages`` like this::
     156
     157   django-admin.py compilemessages
     158
     159That's it. Your translations are ready for use.
     160
     161.. admonition:: A note to Django veterans
     162
     163    The old tool ``bin/compile-messages.py`` has been moved to the command
     164    ``django-admin.py compilemessages`` to provide consistency throughout
     165    Django.
     166
     167.. admonition:: Working on Windows?
     168
     169   If you're using Windows and need to install the GNU gettext utilities so
     170   ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more
     171   information.
     172
     173.. _creating-message-files-from-js-code:
     174
     175Creating message files from JavaScript source code
     176==================================================
     177
     178You create and update the message files the same way as the other Django message
     179files -- with the ``django-admin.py makemessages`` tool. The only difference is
     180you need to provide a ``-d djangojs`` parameter, like this::
     181
     182    django-admin.py makemessages -d djangojs -l de
     183
     184This would create or update the message file  for JavaScript for German.
     185After updating message files, just run ``django-admin.py compilemessages``
     186the same way as you do with normal Django message files.
     187
     188.. _translations-in-your-own-projects:
     189
     190Using translations in your own projects
     191=======================================
     192
     193Django looks for translations by following this algorithm:
     194
     195    * First, it looks for a ``locale`` directory in the application directory
     196      of the view that's being called. If it finds a translation for the
     197      selected language, the translation will be installed.
     198    * Next, it looks for a ``locale`` directory in the project directory. If it
     199      finds a translation, the translation will be installed.
     200    * Finally, it checks the Django-provided base translation in
     201      ``django/conf/locale``.
     202
     203This way, you can write applications that include their own translations, and
     204you can override base translations in your project path. Or, you can just build
     205a big project out of several apps and put all translations into one big project
     206message file. The choice is yours.
     207
     208.. note::
     209
     210    If you're using manually configured settings, as described in
     211    :ref:`settings-without-django-settings-module`, the ``locale`` directory in
     212    the project directory will not be examined, since Django loses the ability
     213    to work out the location of the project directory. (Django normally uses the
     214    location of the settings file to determine this, and a settings file doesn't
     215    exist if you're manually configuring your settings.)
     216
     217All message file repositories are structured the same way. They are:
     218
     219    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     220    * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     221    * All paths listed in ``LOCALE_PATHS`` in your settings file are
     222      searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
     223    * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
     224
     225To create message files, you use the ``django-admin.py makemessages``
     226tool. You only need to be in the same directory where the ``locale/``
     227directory is located. And you use ``django-admin.py compilemessages``
     228to produce the binary ``django.mo`` files that are used by ``gettext``.
     229
     230You can also run ``django-admin.py compilemessages --settings=path.to.settings``
     231to make the compiler process all the directories in your ``LOCALE_PATHS``
     232setting.
     233
     234Application message files are a bit complicated to discover -- they need the
     235``LocaleMiddleware``. If you don't use the middleware, only the Django message
     236files and project message files will be processed.
     237
     238Finally, you should give some thought to the structure of your translation
     239files. If your applications need to be delivered to other users and will
     240be used in other projects, you might want to use app-specific translations.
     241But using app-specific translations and project translations could produce
     242weird problems with ``makemessages``: ``makemessages`` will traverse all
     243directories below the current path and so might put message IDs into the
     244project message file that are already in application message files.
     245
     246The easiest way out is to store applications that are not part of the project
     247(and so carry their own translations) outside the project tree. That way,
     248``django-admin.py makemessages`` on the project level will only translate
     249strings that are connected to your explicit project and not strings that are
     250distributed independently.
     251
     252.. _gettext_on_windows:
     253
     254``gettext`` on Windows
     255======================
     256
     257This is only needed for people who either want to extract message IDs or compile
     258message files (``.po``). Translation work itself just involves editing existing
     259files of this type, but if you want to create your own message files, or want to
     260test or compile a changed message file, you will need the ``gettext`` utilities:
     261
     262    * Download the following zip files from
     263      http://sourceforge.net/projects/gettext
     264
     265      * ``gettext-runtime-X.bin.woe32.zip``
     266      * ``gettext-tools-X.bin.woe32.zip``
     267      * ``libiconv-X.bin.woe32.zip``
     268
     269    * Extract the 3 files in the same folder (i.e. ``C:\Program
     270      Files\gettext-utils``)
     271
     272    * Update the system PATH:
     273
     274      * ``Control Panel > System > Advanced > Environment Variables``
     275      * In the ``System variables`` list, click ``Path``, click ``Edit``
     276      * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
     277        ``Variable value`` field
     278
     279You may also use ``gettext`` binaries you have obtained elsewhere, so long as
     280the ``xgettext --version`` command works properly. Some version 0.14.4 binaries
     281have been found to not support this command. Do not attempt to use Django
     282translation utilities with a ``gettext`` package if the command ``xgettext
     283--version`` entered at a Windows command prompt causes a popup window saying
     284"xgettext.exe has generated errors and will be closed by Windows".
  • docs/topics/index.txt

    diff --git a/docs/topics/index.txt b/docs/topics/index.txt
    a b  
    1919   auth
    2020   cache
    2121   email
    22    i18n
     22   i18n/index
    2323   pagination
    2424   serialization
    2525   settings
Back to Top