Ticket #10260: 10260-post-r11964.diff

File 10260-post-r11964.diff, 100.3 KB (added by Ramiro Morales, 15 years ago)

Patch updated to trunk state after r11964 (locale aware formatting)

  • new file docs/howto/i18n.txt

    diff -r 8a4e070b280a docs/howto/i18n.txt
    - +  
     1.. _howto-i18n:
     2
     3.. _using-translations-in-your-own-projects:
     4
     5===============================================
     6Using internationalization in your own projects
     7===============================================
     8
     9At runtime, Django looks for translations by following this algorithm:
     10
     11    * First, it looks for a ``locale`` directory in the application directory
     12      of the view that's being called. If it finds a translation for the
     13      selected language, the translation will be installed.
     14    * Next, it looks for a ``locale`` directory in the project directory. If it
     15      finds a translation, the translation will be installed.
     16    * Finally, it checks the Django-provided base translation in
     17      ``django/conf/locale``.
     18
     19This way, you can write applications that include their own translations, and
     20you can override base translations in your project path. Or, you can just build
     21a big project out of several apps and put all translations into one big project
     22message file. The choice is yours.
     23
     24.. note::
     25
     26    If you're using manually configured settings, as described in
     27    :ref:`settings-without-django-settings-module`, the ``locale`` directory in
     28    the project directory will not be examined, since Django loses the ability
     29    to work out the location of the project directory. (Django normally uses the
     30    location of the settings file to determine this, and a settings file doesn't
     31    exist if you're manually configuring your settings.)
     32
     33All message file repositories are structured the same way. They are:
     34
     35    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     36    * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     37    * All paths listed in ``LOCALE_PATHS`` in your settings file are
     38      searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
     39    * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
     40
     41To create message files, you use the ``django-admin.py makemessages`` tool. You
     42only need to be in the same directory where the ``locale/`` directory is
     43located. And you use ``django-admin.py compilemessages`` to produce the binary
     44``.mo`` files that are used by ``gettext``. Read the
     45:ref:`topics-i18n-localization` document for more details.
     46
     47You can also run ``django-admin.py compilemessages --settings=path.to.settings``
     48to make the compiler process all the directories in your ``LOCALE_PATHS``
     49setting.
     50
     51Application message files are a bit complicated to discover -- they need the
     52``LocaleMiddleware``. If you don't use the middleware, only the Django message
     53files and project message files will be installed and available at runtime.
     54
     55Finally, you should give some thought to the structure of your translation
     56files. If your applications need to be delivered to other users and will
     57be used in other projects, you might want to use app-specific translations.
     58But using app-specific translations and project translations could produce
     59weird problems with ``makemessages``: ``makemessages`` will traverse all
     60directories below the current path and so might put message IDs into the
     61project message file that are already in application message files.
     62
     63The easiest way out is to store applications that are not part of the project
     64(and so carry their own translations) outside the project tree. That way,
     65``django-admin.py makemessages`` on the project level will only translate
     66strings that are connected to your explicit project and not strings that are
     67distributed independently.
  • docs/howto/index.txt

    diff -r 8a4e070b280a docs/howto/index.txt
    a b  
    2020   deployment/index
    2121   error-reporting
    2222   initial-data
     23   i18n
    2324   jython
    2425   legacy-databases
    2526   outputting-csv
  • docs/internals/contributing.txt

    diff -r 8a4e070b280a docs/internals/contributing.txt
    a b  
    402402
    403403    * Join the `Django i18n mailing list`_ and introduce yourself.
    404404
     405    * Make sure you read the notes about :ref:`specialties-of-django-i18n`.
     406
    405407    * 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.
     408      :ref:`localization documentation <topics-i18n-localization>`. For this
     409      you will use the ``django-admin.py makemessages`` tool. In this
     410      particular case it should be run from the top-level ``django`` directory
     411      of the Django source tree.
    409412
    410413      The script runs over the entire Django source tree and pulls out all
    411414      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``).
     415      the directory ``conf/locale`` (for example for ``pt_BR``, the file will be
     416      ``conf/locale/pt_BR/LC_MESSAGES/django.po``).
    414417
    415418    * Make sure that ``django-admin.py compilemessages -l <lang>`` runs without
    416419      producing any warnings.
     
    419422      ``-d djangojs`` command line option to the ``django-admin.py``
    420423      invocations).
    421424
    422     * Create a diff of the ``.po`` file(s) against the current Subversion trunk.
     425    * Optionally, review and update the ``conf/locale/<locale>/formats.py``
     426      file to describe the date, time and numbers formatting particularities of
     427      your locale . See :ref:`format-localization` for details.
     428
     429    * Create a diff against the current Subversion trunk.
    423430
    424431    * Open a ticket in Django's ticket system, set its ``Component`` field to
    425432      ``Translations``, and attach the patch to it.
  • docs/ref/settings.txt

    diff -r 8a4e070b280a docs/ref/settings.txt
    a b  
    917917Default: ``()`` (Empty tuple)
    918918
    919919A tuple of directories where Django looks for translation files.
    920 See :ref:`translations-in-your-own-projects`.
     920See :ref:`using-translations-in-your-own-projects`.
    921921
    922922.. setting:: LOGIN_REDIRECT_URL
    923923
  • deleted file docs/topics/i18n.txt

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

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

    diff -r 8a4e070b280a docs/topics/i18n/index.txt
    - +  
     1.. _topics-i18n:
     2
     3=====================================
     4Internationalization and localization
     5=====================================
     6
     7Overview
     8========
     9
     10Django has full support for internationalization of text in code and
     11templates, and format localization of dates and numbers. Here's how it works.
     12
     13Essentially, Django does two things:
     14
     15    * It lets developers and template authors specify which parts of their apps
     16      should be translatable.
     17    * It uses these hooks to translate Web apps for particular users according
     18      to their language preferences.
     19
     20The complete process can be seen as divided in three stages. It is also possible
     21to identify an identical number of roles with very well defined responsabilities
     22associated with each of these tasks (although it's perfectly normal if you
     23find yourself performing more than one of these roles):
     24
     25    * For applicacion authors wishing to make sure their Django apps can be
     26      used in different locales: Internationalization.
     27    * For translators wanting to translate Django apps: Localization.
     28    * For system administrators/final users setting up internationalized apps or
     29      developers integrating third party apps: Deployment.
     30
     31.. toctree::
     32   :maxdepth: 1
     33
     34   internationalization
     35   localization
     36   deployment
     37
     38.. _ seealso::
     39
     40For more general information about the topic, see the `GNU gettext documentation`_
     41and the `Wikipedia article`_
     42
     43.. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts
     44.. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization
     45
     46.. _specialties-of-django-i18n:
     47
     48Specialties of Django translation
     49==================================
     50
     51Django's translation machinery uses the standard ``gettext`` module that comes
     52with Python. If you know ``gettext``, you might note these specialties in the
     53way Django does translation:
     54
     55    * The string domain is ``django`` or ``djangojs``. This string domain is
     56      used to differentiate between different programs that store their data
     57      in a common message-file library (usually ``/usr/share/locale/``). The
     58      ``django`` domain is used for python and template translation strings
     59      and is loaded into the global translation catalogs. The ``djangojs``
     60      domain is only used for JavaScript translation catalogs to make sure
     61      that those are as small as possible.
     62    * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
     63      ``xgettext`` and ``msgfmt``. This is mostly for convenience.
     64
     65.. _technical-messages:
     66
     67Django technical message IDs
     68----------------------------
     69
     70.. versionchanged:: 1.2
     71    Starting with Django 1.2, technical message IDs are being replaced by :ref:`format-localization`
     72
     73Django uses **technical message IDs** to translate date formats and time
     74formats. Technical message IDs are message strings and can be easily recognized;
     75they're all upper case. You don't translate the message ID as with other message
     76strings, you provide the correct local variant on the provided English value.
     77The format is identical to the format strings used by the ``now`` template tag.
     78
     79For example, with ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``),
     80this would be the format string that you want to use in your language. A Django
     81contributor localizing it to Spanish probably would provide a ``"j N Y P"``
     82"translation" for it in the relevant ``django.po`` file::
     83
     84    msgid "DATETIME_FORMAT"
     85    msgstr "j N Y P"
  • new file docs/topics/i18n/internationalization.txt

    diff -r 8a4e070b280a docs/topics/i18n/internationalization.txt
    - +  
     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 and locales.
     12
     13For text translations, you, the Django developer, can accomplish this goal by
     14adding a minimal amount of hooks to your Python and templates. These hooks
     15are called **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.
     122
     123``ungettext`` takes three arguments: the singular translation string, the plural
     124translation string and the number of objects.
     125
     126This function is useful when your need you Django application to be localizable
     127to languages where the number and complexity of `plural forms
     128<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
     129greater than the two forms used in English ('object' for the singular and
     130'objects' for all the cases where ``count`` is different from zero, irrespective
     131of its value.)
     132
     133For example::
     134
     135    from django.utils.translation import ungettext
     136    def hello_world(request, count):
     137        page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
     138            'count': count,
     139        }
     140        return HttpResponse(page)
     141
     142In this example the number of objects is passed to the translation languages as
     143the ``count`` variable.
     144
     145Lets see a slightly more complex usage example::
     146
     147    from django.utils.translation import ungettext
     148
     149    count = Report.objects.count()
     150    if count == 1:
     151        name = Report._meta.verbose_name
     152    else:
     153        name = Report._meta.verbose_name_plural
     154
     155    text = ungettext(
     156            'There is %(count)d %(name)s available.',
     157            'There are %(count)d %(name)s available.',
     158            count
     159    ) % {
     160        'count': count,
     161        'name': name
     162    }
     163
     164Here we reuse localizable, hopefully already translated literals (contained in
     165the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for
     166other parts of the sentence so all of it is consistently based on the
     167cardinality of the elements at play.
     168
     169.. _pluralization-var-notes:
     170
     171.. note::
     172
     173    When using this technique, make sure you use a single name for every
     174    extrapolated variable included in the literal. In the example above note how
     175    we used the ``name`` Python variable in both translation strings. This
     176    example would fail::
     177
     178        from django.utils.translation import ungettext
     179        from myapp.models import Report
     180
     181        count = Report.objects.count()
     182        d = {
     183            'count': count,
     184            'name': Report._meta.verbose_name
     185            'plural_name': Report._meta.verbose_name_plural
     186        }
     187        text = ungettext(
     188                'There is %(count)d %(name)s available.',
     189                'There are %(count)d %(plural_name)s available.',
     190                count
     191        ) % d
     192
     193    You would get a ``a format specification for argument 'name', as in
     194    'msgstr[0]', doesn't exist in 'msgid'`` error when running
     195    ``django-admin.py compilemessages`` or a ``KeyError`` Python exception at
     196    runtime.
     197
     198.. _lazy-translations:
     199
     200Lazy translation
     201----------------
     202
     203Use the function ``django.utils.translation.ugettext_lazy()`` to translate
     204strings lazily -- when the value is accessed rather than when the
     205``ugettext_lazy()`` function is called.
     206
     207For example, to translate a model's ``help_text``, do the following::
     208
     209    from django.utils.translation import ugettext_lazy
     210
     211    class MyThing(models.Model):
     212        name = models.CharField(help_text=ugettext_lazy('This is the help text'))
     213
     214In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
     215not the actual translation. The translation itself will be done when the string
     216is used in a string context, such as template rendering on the Django admin
     217site.
     218
     219The result of a ``ugettext_lazy()`` call can be used wherever you would use a
     220unicode string (an object with type ``unicode``) in Python. If you try to use
     221it where a bytestring (a ``str`` object) is expected, things will not work as
     222expected, since a ``ugettext_lazy()`` object doesn't know how to convert
     223itself to a bytestring.  You can't use a unicode string inside a bytestring,
     224either, so this is consistent with normal Python behavior. For example::
     225
     226    # This is fine: putting a unicode proxy into a unicode string.
     227    u"Hello %s" % ugettext_lazy("people")
     228
     229    # This will not work, since you cannot insert a unicode object
     230    # into a bytestring (nor can you insert our unicode proxy there)
     231    "Hello %s" % ugettext_lazy("people")
     232
     233If you ever see output that looks like ``"hello
     234<django.utils.functional...>"``, you have tried to insert the result of
     235``ugettext_lazy()`` into a bytestring. That's a bug in your code.
     236
     237If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
     238``_`` (underscore), like so::
     239
     240    from django.utils.translation import ugettext_lazy as _
     241
     242    class MyThing(models.Model):
     243        name = models.CharField(help_text=_('This is the help text'))
     244
     245Always use lazy translations in :ref:`Django models <topics-db-models>`.
     246Field names and table names should be marked for translation (otherwise, they
     247won't be translated in the admin interface). This means writing explicit
     248``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,
     249though, rather than relying on Django's default determination of
     250``verbose_name`` and ``verbose_name_plural`` by looking at the model's class
     251name::
     252
     253    from django.utils.translation import ugettext_lazy as _
     254
     255    class MyThing(models.Model):
     256        name = models.CharField(_('name'), help_text=_('This is the help text'))
     257        class Meta:
     258            verbose_name = _('my thing')
     259            verbose_name_plural = _('mythings')
     260
     261Working with lazy translation objects
     262-------------------------------------
     263
     264.. highlightlang:: python
     265
     266Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
     267and utility functions is a common operation. When you're working with these
     268objects elsewhere in your code, you should ensure that you don't accidentally
     269convert them to strings, because they should be converted as late as possible
     270(so that the correct locale is in effect). This necessitates the use of a
     271couple of helper functions.
     272
     273Joining strings: string_concat()
     274~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     275
     276Standard Python string joins (``''.join([...])``) will not work on lists
     277containing lazy translation objects. Instead, you can use
     278``django.utils.translation.string_concat()``, which creates a lazy object that
     279concatenates its contents *and* converts them to strings only when the result
     280is included in a string. For example::
     281
     282    from django.utils.translation import string_concat
     283    ...
     284    name = ugettext_lazy(u'John Lennon')
     285    instrument = ugettext_lazy(u'guitar')
     286    result = string_concat([name, ': ', instrument])
     287
     288In this case, the lazy translations in ``result`` will only be converted to
     289strings when ``result`` itself is used in a string (usually at template
     290rendering time).
     291
     292The allow_lazy() decorator
     293~~~~~~~~~~~~~~~~~~~~~~~~~~
     294
     295Django offers many utility functions (particularly in ``django.utils``) that
     296take a string as their first argument and do something to that string. These
     297functions are used by template filters as well as directly in other code.
     298
     299If you write your own similar functions and deal with translations, you'll
     300face the problem of what to do when the first argument is a lazy translation
     301object. You don't want to convert it to a string immediately, because you might
     302be using this function outside of a view (and hence the current thread's locale
     303setting will not be correct).
     304
     305For cases like this, use the ``django.utils.functional.allow_lazy()``
     306decorator. It modifies the function so that *if* it's called with a lazy
     307translation as the first argument, the function evaluation is delayed until it
     308needs to be converted to a string.
     309
     310For example::
     311
     312    from django.utils.functional import allow_lazy
     313
     314    def fancy_utility_function(s, ...):
     315        # Do some conversion on string 's'
     316        ...
     317    fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
     318
     319The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
     320a number of extra arguments (``*args``) specifying the type(s) that the
     321original function can return. Usually, it's enough to include ``unicode`` here
     322and ensure that your function returns only Unicode strings.
     323
     324Using this decorator means you can write your function and assume that the
     325input is a proper string, then add support for lazy translation objects at the
     326end.
     327
     328Specifying translation strings: In template code
     329================================================
     330
     331.. highlightlang:: html+django
     332
     333Translations in :ref:`Django templates <topics-templates>` uses two template
     334tags and a slightly different syntax than in Python code. To give your template
     335access to these tags, put ``{% load i18n %}`` toward the top of your template.
     336
     337The ``{% trans %}`` template tag translates either a constant string
     338(enclosed in single or double quotes) or variable content::
     339
     340    <title>{% trans "This is the title." %}</title>
     341    <title>{% trans myvar %}</title>
     342
     343If the ``noop`` option is present, variable lookup still takes place but the
     344translation is skipped. This is useful when "stubbing out" content that will
     345require translation in the future::
     346
     347    <title>{% trans "myvar" noop %}</title>
     348
     349Internally, inline translations use an ``ugettext`` call.
     350
     351It's not possible to mix a template variable inside a string within ``{% trans
     352%}``. If your translations require strings with variables (placeholders), use
     353``{% blocktrans %}``::
     354
     355    {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
     356
     357To translate a template expression -- say, using template filters -- you need
     358to bind the expression to a local variable for use within the translation
     359block::
     360
     361    {% blocktrans with value|filter as myvar %}
     362    This will have {{ myvar }} inside.
     363    {% endblocktrans %}
     364
     365If you need to bind more than one expression inside a ``blocktrans`` tag,
     366separate the pieces with ``and``::
     367
     368    {% blocktrans with book|title as book_t and author|title as author_t %}
     369    This is {{ book_t }} by {{ author_t }}
     370    {% endblocktrans %}
     371
     372To pluralize, specify both the singular and plural forms with the
     373``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and
     374``{% endblocktrans %}``. Example::
     375
     376    {% blocktrans count list|length as counter %}
     377    There is only one {{ name }} object.
     378    {% plural %}
     379    There are {{ counter }} {{ name }} objects.
     380    {% endblocktrans %}
     381
     382When you use the pluralization feature and bind additional values to local
     383variables apart from the counter value that selects the translated literal to be
     384used, have in mind that the ``blocktrans`` construct is internally converted
     385to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext
     386variables <pluralization-var-notes>` apply.
     387
     388Each ``RequestContext`` has access to three translation-specific variables:
     389
     390    * ``LANGUAGES`` is a list of tuples in which the first element is the
     391      language code and the second is the language name (translated into the
     392      currently active locale).
     393
     394    * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
     395      Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`,
     396      below.)
     397
     398    * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
     399      right-to-left language, e.g.: Hebrew, Arabic. If False it's a
     400      left-to-right language, e.g.: English, French, German etc.
     401
     402
     403If you don't use the ``RequestContext`` extension, you can get those values with
     404three tags::
     405
     406    {% get_current_language as LANGUAGE_CODE %}
     407    {% get_available_languages as LANGUAGES %}
     408    {% get_current_language_bidi as LANGUAGE_BIDI %}
     409
     410These tags also require a ``{% load i18n %}``.
     411
     412Translation hooks are also available within any template block tag that accepts
     413constant strings. In those cases, just use ``_()`` syntax to specify a
     414translation string::
     415
     416    {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
     417
     418In this case, both the tag and the filter will see the already-translated
     419string, so they don't need to be aware of translations.
     420
     421.. note::
     422    In this example, the translation infrastructure will be passed the string
     423    ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
     424    translated string will need to contain the comma so that the filter
     425    parsing code knows how to split up the arguments. For example, a German
     426    translator might translate the string ``"yes,no"`` as ``"ja,nein"``
     427    (keeping the comma intact).
     428
     429.. _Django templates: ../templates_python/
     430
     431Specifying translation strings: In JavaScript code
     432==================================================
     433
     434Adding translations to JavaScript poses some problems:
     435
     436    * JavaScript code doesn't have access to a ``gettext`` implementation.
     437
     438    * JavaScript code doesn't have access to .po or .mo files; they need to be
     439      delivered by the server.
     440
     441    * The translation catalogs for JavaScript should be kept as small as
     442      possible.
     443
     444Django provides an integrated solution for these problems: It passes the
     445translations into JavaScript, so you can call ``gettext``, etc., from within
     446JavaScript.
     447
     448The ``javascript_catalog`` view
     449-------------------------------
     450
     451The main solution to these problems is the ``javascript_catalog`` view, which
     452sends out a JavaScript code library with functions that mimic the ``gettext``
     453interface, plus an array of translation strings. Those translation strings are
     454taken from the application, project or Django core, according to what you
     455specify in either the info_dict or the URL.
     456
     457You hook it up like this::
     458
     459    js_info_dict = {
     460        'packages': ('your.app.package',),
     461    }
     462
     463    urlpatterns = patterns('',
     464        (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
     465    )
     466
     467Each string in ``packages`` should be in Python dotted-package syntax (the
     468same format as the strings in ``INSTALLED_APPS``) and should refer to a package
     469that contains a ``locale`` directory. If you specify multiple packages, all
     470those catalogs are merged into one catalog. This is useful if you have
     471JavaScript that uses strings from different applications.
     472
     473You can make the view dynamic by putting the packages into the URL pattern::
     474
     475    urlpatterns = patterns('',
     476        (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
     477    )
     478
     479With this, you specify the packages as a list of package names delimited by '+'
     480signs in the URL. This is especially useful if your pages use code from
     481different apps and this changes often and you don't want to pull in one big
     482catalog file. As a security measure, these values can only be either
     483``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
     484
     485Using the JavaScript translation catalog
     486----------------------------------------
     487
     488To use the catalog, just pull in the dynamically generated script like this::
     489
     490    <script type="text/javascript" src={% url django.views.i18n.javascript_catalog %}"></script>
     491
     492This uses reverse URL lookup to find the URL of the JavaScript catalog view.
     493When the catalog is loaded, your JavaScript code can use the standard
     494``gettext`` interface to access it::
     495
     496    document.write(gettext('this is to be translated'));
     497
     498There is also an ``ngettext`` interface::
     499
     500    var object_cnt = 1 // or 0, or 2, or 3, ...
     501    s = ngettext('literal for the singular case',
     502            'literal for the plural case', object_cnt);
     503
     504and even a string interpolation function::
     505
     506    function interpolate(fmt, obj, named);
     507
     508The interpolation syntax is borrowed from Python, so the ``interpolate``
     509function supports both positional and named interpolation:
     510
     511    * Positional interpolation: ``obj`` contains a JavaScript Array object
     512      whose elements values are then sequentially interpolated in their
     513      corresponding ``fmt`` placeholders in the same order they appear.
     514      For example::
     515
     516        fmts = ngettext('There is %s object. Remaining: %s',
     517                'There are %s objects. Remaining: %s', 11);
     518        s = interpolate(fmts, [11, 20]);
     519        // s is 'There are 11 objects. Remaining: 20'
     520
     521    * Named interpolation: This mode is selected by passing the optional
     522      boolean ``named`` parameter as true. ``obj`` contains a JavaScript
     523      object or associative array. For example::
     524
     525        d = {
     526            count: 10
     527            total: 50
     528        };
     529
     530        fmts = ngettext('Total: %(total)s, there is %(count)s object',
     531        'there are %(count)s of a total of %(total)s objects', d.count);
     532        s = interpolate(fmts, d, true);
     533
     534You shouldn't go over the top with string interpolation, though: this is still
     535JavaScript, so the code has to make repeated regular-expression substitutions.
     536This isn't as fast as string interpolation in Python, so keep it to those
     537cases where you really need it (for example, in conjunction with ``ngettext``
     538to produce proper pluralizations).
     539
     540The ``set_language`` redirect view
     541==================================
     542
     543As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
     544that sets a user's language preference and redirects back to the previous page.
     545
     546Activate this view by adding the following line to your URLconf::
     547
     548    (r'^i18n/', include('django.conf.urls.i18n')),
     549
     550(Note that this example makes the view available at ``/i18n/setlang/``.)
     551
     552The view expects to be called via the ``POST`` method, with a ``language``
     553parameter set in request. If session support is enabled, the view
     554saves the language choice in the user's session. Otherwise, it saves the
     555language choice in a cookie that is by default named ``django_language``.
     556(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
     557
     558After setting the language choice, Django redirects the user, following this
     559algorithm:
     560
     561    * Django looks for a ``next`` parameter in the ``POST`` data.
     562    * If that doesn't exist, or is empty, Django tries the URL in the
     563      ``Referrer`` header.
     564    * If that's empty -- say, if a user's browser suppresses that header --
     565      then the user will be redirected to ``/`` (the site root) as a fallback.
     566
     567Here's example HTML template code:
     568
     569.. code-block:: html+django
     570
     571    <form action="/i18n/setlang/" method="post">
     572    <input name="next" type="hidden" value="/next/page/" />
     573    <select name="language">
     574    {% for lang in LANGUAGES %}
     575    <option value="{{ lang.0 }}">{{ lang.1 }}</option>
     576    {% endfor %}
     577    </select>
     578    <input type="submit" value="Go" />
     579    </form>
  • new file docs/topics/i18n/localization.txt

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

    diff -r 8a4e070b280a docs/topics/index.txt
    a b  
    2121   cache
    2222   conditional-view-processing
    2323   email
    24    i18n
     24   i18n/index
    2525   pagination
    2626   serialization
    2727   settings
Back to Top