Ticket #10260: 10260-i18n-docs-rf-1.1.x-r12229.diff

File 10260-i18n-docs-rf-1.1.x-r12229.diff, 97.4 KB (added by Ramiro Morales, 14 years ago)

Patch for 1.1.x branch as of r12229.

  • new file docs/howto/i18n.txt

    diff -r 4755c937c02f 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
     19In all cases the name of the directory containing the translation is expected to
     20be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
     21etc.
     22
     23This way, you can write applications that include their own translations, and
     24you can override base translations in your project path. Or, you can just build
     25a big project out of several apps and put all translations into one big project
     26message file. The choice is yours.
     27
     28.. note::
     29
     30    If you're using manually configured settings, as described in
     31    :ref:`settings-without-django-settings-module`, the ``locale`` directory in
     32    the project directory will not be examined, since Django loses the ability
     33    to work out the location of the project directory. (Django normally uses the
     34    location of the settings file to determine this, and a settings file doesn't
     35    exist if you're manually configuring your settings.)
     36
     37All message file repositories are structured the same way. They are:
     38
     39    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     40    * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
     41    * All paths listed in ``LOCALE_PATHS`` in your settings file are
     42      searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
     43    * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
     44
     45To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
     46tool. You only need to be in the same directory where the ``locale/`` directory
     47is located. And you use :djadmin:`django-admin.py compilemessages <compilemessages>`
     48to produce the binary ``.mo`` files that are used by ``gettext``. Read the
     49:ref:`topics-i18n-localization` document for more details.
     50
     51You can also run ``django-admin.py compilemessages --settings=path.to.settings``
     52to make the compiler process all the directories in your :setting:`LOCALE_PATHS`
     53setting.
     54
     55Application message files are a bit complicated to discover -- they need the
     56:class:`~django.middleware.locale.LocaleMiddleware`. If you don't use the
     57middleware, only the Django message files and project message files will be
     58installed and available at runtime.
     59
     60Finally, you should give some thought to the structure of your translation
     61files. If your applications need to be delivered to other users and will
     62be used in other projects, you might want to use app-specific translations.
     63But using app-specific translations and project translations could produce
     64weird problems with ``makemessages``: It will traverse all directories below
     65the current path and so might put message IDs into the project message file
     66that are already in application message files.
     67
     68The easiest way out is to store applications that are not part of the project
     69(and so carry their own translations) outside the project tree. That way,
     70``django-admin.py makemessages`` on the project level will only translate
     71strings that are connected to your explicit project and not strings that are
     72distributed independently.
  • docs/howto/index.txt

    diff -r 4755c937c02f 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 4755c937c02f 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.
  • docs/ref/settings.txt

    diff -r 4755c937c02f docs/ref/settings.txt
    a b  
    610610Default: ``'en-us'``
    611611
    612612A string representing the language code for this installation. This should be in
    613 standard language format. For example, U.S. English is ``"en-us"``. See
    614 :ref:`topics-i18n`.
     613standard :term:`language format<language code>`. For example, U.S. English is
     614``"en-us"``. See :ref:`topics-i18n`.
    615615
    616616.. setting:: LANGUAGE_COOKIE_NAME
    617617
     
    638638
    639639.. _online source: http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py
    640640
    641 The list is a tuple of two-tuples in the format (language code, language
    642 name) -- for example, ``('ja', 'Japanese')``. This specifies which languages
    643 are available for language selection. See :ref:`topics-i18n`.
     641The list is a tuple of two-tuples in the format ``(language code, language
     642name)``, the ``language code`` part should be a
     643:term:`language name<language code>` -- for example, ``('ja', 'Japanese')``.
     644This specifies which languages are available for language selection. See
     645:ref:`topics-i18n`.
    644646
    645647Generally, the default value should suffice. Only set this setting if you want
    646648to restrict language selection to a subset of the Django-provided languages.
     
    675677Default: ``()`` (Empty tuple)
    676678
    677679A tuple of directories where Django looks for translation files.
    678 See :ref:`translations-in-your-own-projects`.
     680See :ref:`using-translations-in-your-own-projects`.
    679681
    680682.. setting:: LOGIN_REDIRECT_URL
    681683
  • deleted file docs/topics/i18n.txt

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

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

    diff -r 4755c937c02f 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 templates.
     11
     12Essentially, Django does two things:
     13
     14    * It lets developers and template authors specify which parts of their apps
     15      should be translatable.
     16    * It uses these hooks to translate Web apps for particular users according
     17      to their language preferences.
     18
     19The complete process can be seen as divided in three stages. It is also possible
     20to identify an identical number of roles with very well defined responsabilities
     21associated with each of these tasks (although it's perfectly normal if you
     22find yourself performing more than one of these roles):
     23
     24    * For applicacion authors wishing to make sure their Django apps can be
     25      used in different locales: Internationalization.
     26    * For translators wanting to translate Django apps: Localization.
     27    * For system administrators/final users setting up internationalized apps or
     28      developers integrating third party apps: Deployment.
     29
     30.. toctree::
     31   :maxdepth: 1
     32
     33   internationalization
     34   localization
     35   deployment
     36
     37.. _ seealso::
     38
     39For more general information about the topic, see the `GNU gettext documentation`_
     40and the `Wikipedia article`_
     41
     42.. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts
     43.. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization
     44
     45Glossary
     46========
     47
     48First lets define some terms that will help us to handle a common language:
     49
     50.. glossary::
     51
     52    locale name
     53      A locale name, either a language specification of the form ``ll`` or a
     54      combined language and country specification of the form ``ll_CC``.
     55      Examples: ``it``, ``de_AT``, ``es``, ``pt_BR``. Note the underscore in
     56      some of them and the case of the part located to its right.
     57
     58    language code
     59      Represents the name of a language. Browsers send the names of the
     60      languages they accept in the ``Accept-Language`` HTTP header using this
     61      format. Examples: ``it``, ``de-at``, ``es``, ``pt-br``. Note the ``-``
     62      separator.
     63
     64    message file
     65      A message file is a plain-text file, representing a single language, that
     66      contains all available :term:`translation string`\s and how they should be
     67      represented in the given language. Message files have a ``.po`` file
     68      extension.
     69
     70    translation string
     71      A literal that can be translated.
     72
     73.. _specialties-of-django-i18n:
     74
     75Specialties of Django translation
     76==================================
     77
     78Django's translation machinery uses the standard ``gettext`` module that comes
     79with Python. If you know ``gettext``, you might note these specialties in the
     80way Django does translation:
     81
     82    * The string domain is ``django`` or ``djangojs``. This string domain is
     83      used to differentiate between different programs that store their data
     84      in a common message-file library (usually ``/usr/share/locale/``). The
     85      ``django`` domain is used for python and template translation strings
     86      and is loaded into the global translation catalogs. The ``djangojs``
     87      domain is only used for JavaScript translation catalogs to make sure
     88      that those are as small as possible.
     89    * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
     90      ``xgettext`` and ``msgfmt``. This is mostly for convenience.
     91
     92.. _technical-messages:
     93
     94Django technical message IDs
     95----------------------------
     96
     97Django uses technical message IDs to translate date formats and time formats.
     98Technical message IDs are :term:`translation string`\s and can be easily
     99recognized; they're all upper case. You don't translate the message ID as with
     100other translation strings, you provide the correct local variant on the provided
     101English value.  The format is identical to the format strings used by the
     102``now`` template tag.
     103
     104For example, with ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``),
     105this would be the format string that you want to use in your language. A Django
     106contributor localizing it to Spanish probably would provide a ``"j N Y P"``
     107"translation" for it in the relevant ``django.po`` file::
     108
     109    msgid "DATETIME_FORMAT"
     110    msgstr "j N Y P"
  • new file docs/topics/i18n/internationalization.txt

    diff -r 4755c937c02f 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.
     12
     13You, the Django developer, can accomplish this goal by adding a minimal amount
     14xof hooks to your Python (and JavaScript) code and templates. These hooks are
     15called **translation strings**. They tell Django: "This text should be
     16translated into the end user's language, if a translation for this text is
     17available in that language." It's your responsibility to mark translatable
     18strings; the system can only translate strings it knows about.
     19
     20Django takes care of using these hooks to translate Web apps, on the fly,
     21according to users' language preferences.
     22
     23Specifying translation strings: In Python code
     24==============================================
     25
     26Standard translation
     27--------------------
     28
     29Specify a translation string by using the function ``ugettext()``. It's
     30convention to import this as a shorter alias, ``_``, to save typing.
     31
     32.. note::
     33    Python's standard library ``gettext`` module installs ``_()`` into the
     34    global namespace, as an alias for ``gettext()``. In Django, we have chosen
     35    not to follow this practice, for a couple of reasons:
     36
     37      1. For international character set (Unicode) support, ``ugettext()`` is
     38         more useful than ``gettext()``. Sometimes, you should be using
     39         ``ugettext_lazy()`` as the default translation method for a particular
     40         file. Without ``_()`` in the global namespace, the developer has to
     41         think about which is the most appropriate translation function.
     42
     43      2. The underscore character (``_``) is used to represent "the previous
     44         result" in Python's interactive shell and doctest tests. Installing a
     45         global ``_()`` function causes interference. Explicitly importing
     46         ``ugettext()`` as ``_()`` avoids this problem.
     47
     48.. highlightlang:: python
     49
     50In this example, the text ``"Welcome to my site."`` is marked as a translation
     51string::
     52
     53    from django.utils.translation import ugettext as _
     54
     55    def my_view(request):
     56        output = _("Welcome to my site.")
     57        return HttpResponse(output)
     58
     59Obviously, you could code this without using the alias. This example is
     60identical to the previous one::
     61
     62    from django.utils.translation import ugettext
     63
     64    def my_view(request):
     65        output = ugettext("Welcome to my site.")
     66        return HttpResponse(output)
     67
     68Translation works on computed values. This example is identical to the previous
     69two::
     70
     71    def my_view(request):
     72        words = ['Welcome', 'to', 'my', 'site.']
     73        output = _(' '.join(words))
     74        return HttpResponse(output)
     75
     76Translation works on variables. Again, here's an identical example::
     77
     78    def my_view(request):
     79        sentence = 'Welcome to my site.'
     80        output = _(sentence)
     81        return HttpResponse(output)
     82
     83(The caveat with using variables or computed values, as in the previous two
     84examples, is that Django's translation-string-detecting utility,
     85``django-admin.py makemessages``, won't be able to find these strings. More on
     86``makemessages`` later.)
     87
     88The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
     89specified with Python's standard named-string interpolation syntax. Example::
     90
     91    def my_view(request, m, d):
     92        output = _('Today is %(month)s, %(day)s.') % {'month': m, 'day': d}
     93        return HttpResponse(output)
     94
     95This technique lets language-specific translations reorder the placeholder
     96text. For example, an English translation may be ``"Today is November, 26."``,
     97while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
     98placeholders (the month and the day) with their positions swapped.
     99
     100For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
     101instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
     102have more than a single parameter. If you used positional interpolation,
     103translations wouldn't be able to reorder placeholder text.
     104
     105Marking strings as no-op
     106------------------------
     107
     108Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
     109as a translation string without translating it. The string is later translated
     110from a variable.
     111
     112Use this if you have constant strings that should be stored in the source
     113language because they are exchanged over systems or users -- such as strings in
     114a database -- but should be translated at the last possible point in time, such
     115as when the string is presented to the user.
     116
     117Pluralization
     118-------------
     119
     120Use the function ``django.utils.translation.ungettext()`` to specify pluralized
     121messages.
     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 you need your 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      :term:`language code` and the second is the language name (translated into
     392      the 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
     397    * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
     398      right-to-left language, e.g.: Hebrew, Arabic. If False it's a
     399      left-to-right language, e.g.: English, French, German etc.
     400
     401
     402If you don't use the ``RequestContext`` extension, you can get those values with
     403three tags::
     404
     405    {% get_current_language as LANGUAGE_CODE %}
     406    {% get_available_languages as LANGUAGES %}
     407    {% get_current_language_bidi as LANGUAGE_BIDI %}
     408
     409These tags also require a ``{% load i18n %}``.
     410
     411Translation hooks are also available within any template block tag that accepts
     412constant strings. In those cases, just use ``_()`` syntax to specify a
     413translation string::
     414
     415    {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
     416
     417In this case, both the tag and the filter will see the already-translated
     418string, so they don't need to be aware of translations.
     419
     420.. note::
     421    In this example, the translation infrastructure will be passed the string
     422    ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
     423    translated string will need to contain the comma so that the filter
     424    parsing code knows how to split up the arguments. For example, a German
     425    translator might translate the string ``"yes,no"`` as ``"ja,nein"``
     426    (keeping the comma intact).
     427
     428.. _Django templates: ../templates_python/
     429
     430Specifying translation strings: In JavaScript code
     431==================================================
     432
     433Adding translations to JavaScript poses some problems:
     434
     435    * JavaScript code doesn't have access to a ``gettext`` implementation.
     436
     437    * JavaScript code doesn't have access to .po or .mo files; they need to be
     438      delivered by the server.
     439
     440    * The translation catalogs for JavaScript should be kept as small as
     441      possible.
     442
     443Django provides an integrated solution for these problems: It passes the
     444translations into JavaScript, so you can call ``gettext``, etc., from within
     445JavaScript.
     446
     447The ``javascript_catalog`` view
     448-------------------------------
     449
     450The main solution to these problems is the ``javascript_catalog`` view, which
     451sends out a JavaScript code library with functions that mimic the ``gettext``
     452interface, plus an array of translation strings. Those translation strings are
     453taken from the application, project or Django core, according to what you
     454specify in either the info_dict or the URL.
     455
     456You hook it up like this::
     457
     458    js_info_dict = {
     459        'packages': ('your.app.package',),
     460    }
     461
     462    urlpatterns = patterns('',
     463        (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
     464    )
     465
     466Each string in ``packages`` should be in Python dotted-package syntax (the
     467same format as the strings in ``INSTALLED_APPS``) and should refer to a package
     468that contains a ``locale`` directory. If you specify multiple packages, all
     469those catalogs are merged into one catalog. This is useful if you have
     470JavaScript that uses strings from different applications.
     471
     472You can make the view dynamic by putting the packages into the URL pattern::
     473
     474    urlpatterns = patterns('',
     475        (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
     476    )
     477
     478With this, you specify the packages as a list of package names delimited by '+'
     479signs in the URL. This is especially useful if your pages use code from
     480different apps and this changes often and you don't want to pull in one big
     481catalog file. As a security measure, these values can only be either
     482``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
     483
     484Using the JavaScript translation catalog
     485----------------------------------------
     486
     487To use the catalog, just pull in the dynamically generated script like this::
     488
     489    <script type="text/javascript" src={% url django.views.i18n.javascript_catalog %}"></script>
     490
     491This uses reverse URL lookup to find the URL of the JavaScript catalog view.
     492When the catalog is loaded, your JavaScript code can use the standard
     493``gettext`` interface to access it::
     494
     495    document.write(gettext('this is to be translated'));
     496
     497There is also an ``ngettext`` interface::
     498
     499    var object_cnt = 1 // or 0, or 2, or 3, ...
     500    s = ngettext('literal for the singular case',
     501            'literal for the plural case', object_cnt);
     502
     503and even a string interpolation function::
     504
     505    function interpolate(fmt, obj, named);
     506
     507The interpolation syntax is borrowed from Python, so the ``interpolate``
     508function supports both positional and named interpolation:
     509
     510    * Positional interpolation: ``obj`` contains a JavaScript Array object
     511      whose elements values are then sequentially interpolated in their
     512      corresponding ``fmt`` placeholders in the same order they appear.
     513      For example::
     514
     515        fmts = ngettext('There is %s object. Remaining: %s',
     516                'There are %s objects. Remaining: %s', 11);
     517        s = interpolate(fmts, [11, 20]);
     518        // s is 'There are 11 objects. Remaining: 20'
     519
     520    * Named interpolation: This mode is selected by passing the optional
     521      boolean ``named`` parameter as true. ``obj`` contains a JavaScript
     522      object or associative array. For example::
     523
     524        d = {
     525            count: 10
     526            total: 50
     527        };
     528
     529        fmts = ngettext('Total: %(total)s, there is %(count)s object',
     530        'there are %(count)s of a total of %(total)s objects', d.count);
     531        s = interpolate(fmts, d, true);
     532
     533You shouldn't go over the top with string interpolation, though: this is still
     534JavaScript, so the code has to make repeated regular-expression substitutions.
     535This isn't as fast as string interpolation in Python, so keep it to those
     536cases where you really need it (for example, in conjunction with ``ngettext``
     537to produce proper pluralizations).
     538
     539The ``set_language`` redirect view
     540==================================
     541
     542As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
     543that sets a user's language preference and redirects back to the previous page.
     544
     545Activate this view by adding the following line to your URLconf::
     546
     547    (r'^i18n/', include('django.conf.urls.i18n')),
     548
     549(Note that this example makes the view available at ``/i18n/setlang/``.)
     550
     551The view expects to be called via the ``POST`` method, with a ``language``
     552parameter set in request. If session support is enabled, the view
     553saves the language choice in the user's session. Otherwise, it saves the
     554language choice in a cookie that is by default named ``django_language``.
     555(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
     556
     557After setting the language choice, Django redirects the user, following this
     558algorithm:
     559
     560    * Django looks for a ``next`` parameter in the ``POST`` data.
     561    * If that doesn't exist, or is empty, Django tries the URL in the
     562      ``Referrer`` header.
     563    * If that's empty -- say, if a user's browser suppresses that header --
     564      then the user will be redirected to ``/`` (the site root) as a fallback.
     565
     566Here's example HTML template code:
     567
     568.. code-block:: html+django
     569
     570    <form action="/i18n/setlang/" method="post">
     571    <input name="next" type="hidden" value="/next/page/" />
     572    <select name="language">
     573    {% for lang in LANGUAGES %}
     574    <option value="{{ lang.0 }}">{{ lang.1 }}</option>
     575    {% endfor %}
     576    </select>
     577    <input type="submit" value="Go" />
     578    </form>
  • new file docs/topics/i18n/localization.txt

    diff -r 4755c937c02f docs/topics/i18n/localization.txt
    - +  
     1.. _topics-i18n-localization:
     2
     3============
     4Localization
     5============
     6
     7.. seealso::
     8
     9    The :ref:`howto-i18n` document included with the Django HOW-TO documents collection.
     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 :term:`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 :term:`locale format<locale name>`. For
     58example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian
     59German.
     60
     61The script should be run from one of two places:
     62
     63    * The root directory of your Django project.
     64    * The root directory of your Django app.
     65
     66Th script runs over your project source tree or your application source tree and
     67pulls out all strings marked for translation. It creates (or updates) a message
     68file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the
     69file will be ``locale/de/LC_MESSAGES/django.po``.
     70
     71By default ``django-admin.py makemessages`` examines every file that has the
     72``.html`` file extension. In case you want to override that default, use the
     73``--extension`` or ``-e`` option to specify the file extensions to examine::
     74
     75    django-admin.py makemessages -l de -e txt
     76
     77Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
     78multiple times::
     79
     80    django-admin.py makemessages -l=de -e=html,txt -e xml
     81
     82When :ref:`creating message files from JavaScript source code
     83<creating-message-files-from-js-code>` you need to use the special 'djangojs'
     84domain, **not** ``-e js``.
     85
     86.. admonition:: No gettext?
     87
     88    If you don't have the ``gettext`` utilities installed, ``django-admin.py
     89    makemessages`` will create empty files. If that's the case, either install
     90    the ``gettext`` utilities or just copy the English message file
     91    (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
     92    point; it's just an empty translation file.
     93
     94.. admonition:: Working on Windows?
     95
     96   If you're using Windows and need to install the GNU gettext utilities so
     97   ``django-admin makemessages`` works see :ref:`gettext_on_windows` for more
     98   information.
     99
     100The format of ``.po`` files is straightforward. Each ``.po`` file contains a
     101small bit of metadata, such as the translation maintainer's contact
     102information, but the bulk of the file is a list of **messages** -- simple
     103mappings between translation strings and the actual translated text for the
     104particular language.
     105
     106For example, if your Django app contained a translation string for the text
     107``"Welcome to my site."``, like so::
     108
     109    _("Welcome to my site.")
     110
     111...then ``django-admin.py makemessages`` will have created a ``.po`` file
     112containing the following snippet -- a message::
     113
     114    #: path/to/python/module.py:23
     115    msgid "Welcome to my site."
     116    msgstr ""
     117
     118A quick explanation:
     119
     120    * ``msgid`` is the translation string, which appears in the source. Don't
     121      change it.
     122    * ``msgstr`` is where you put the language-specific translation. It starts
     123      out empty, so it's your responsibility to change it. Make sure you keep
     124      the quotes around your translation.
     125    * As a convenience, each message includes, in the form of a comment line
     126      prefixed with ``#`` and located above the ``msgid`` line, the filename and
     127      line number from which the translation string was gleaned.
     128
     129Long messages are a special case. There, the first string directly after the
     130``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
     131written over the next few lines as one string per line. Those strings are
     132directly concatenated. Don't forget trailing spaces within the strings;
     133otherwise, they'll be tacked together without whitespace!
     134
     135.. admonition:: Mind your charset
     136
     137    When creating a PO file with your favorite text editor, first edit
     138    the charset line (search for ``"CHARSET"``) and set it to the charset
     139    you'll be using to edit the content. Due to the way the ``gettext`` tools
     140    work internally and because we want to allow non-ASCII source strings in
     141    Django's core and your applications, you **must** use UTF-8 as the encoding
     142    for your PO file. This means that everybody will be using the same
     143    encoding, which is important when Django processes the PO files.
     144
     145To reexamine all source code and templates for new translation strings and
     146update all message files for **all** languages, run this::
     147
     148    django-admin.py makemessages -a
     149
     150Compiling message files
     151-----------------------
     152
     153After you create your message file -- and each time you make changes to it --
     154you'll need to compile it into a more efficient form, for use by ``gettext``.
     155Do this with the ``django-admin.py compilemessages`` utility.
     156
     157This tool runs over all available ``.po`` files and creates ``.mo`` files, which
     158are binary files optimized for use by ``gettext``. In the same directory from
     159which you ran ``django-admin.py makemessages``, run ``django-admin.py
     160compilemessages`` like this::
     161
     162   django-admin.py compilemessages
     163
     164That's it. Your translations are ready for use.
     165
     166.. admonition:: A note to Django veterans
     167
     168    The old tool ``bin/compile-messages.py`` has been moved to the command
     169    ``django-admin.py compilemessages`` to provide consistency throughout
     170    Django.
     171
     172.. admonition:: Working on Windows?
     173
     174   If you're using Windows and need to install the GNU gettext utilities so
     175   ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more
     176   information.
     177
     178.. _creating-message-files-from-js-code:
     179
     180Creating message files from JavaScript source code
     181==================================================
     182
     183You create and update the message files the same way as the other Django message
     184files -- with the ``django-admin.py makemessages`` tool. The only difference is
     185you need to provide a ``-d djangojs`` parameter, like this::
     186
     187    django-admin.py makemessages -d djangojs -l de
     188
     189This would create or update the message file for JavaScript for German.
     190After updating message files, just run ``django-admin.py compilemessages``
     191the same way as you do with normal Django message files.
     192
     193.. _gettext_on_windows:
     194
     195``gettext`` on Windows
     196======================
     197
     198This is only needed for people who either want to extract message IDs or compile
     199message files (``.po``). Translation work itself just involves editing existing
     200files of this type, but if you want to create your own message files, or want to
     201test or compile a changed message file, you will need the ``gettext`` utilities:
     202
     203    * Download the following zip files from the GNOME servers
     204      http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
     205      of its mirrors_
     206
     207      * ``gettext-runtime-X.zip``
     208      * ``gettext-tools-X.zip``
     209
     210      ``X`` is the version number, we recomend using ``0.15`` or higher.
     211
     212    * Extract the contents of the ``bin\`` directories in both files to the
     213      same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
     214
     215    * Update the system PATH:
     216
     217      * ``Control Panel > System > Advanced > Environment Variables``.
     218      * In the ``System variables`` list, click ``Path``, click ``Edit``.
     219      * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
     220        ``Variable value`` field.
     221
     222.. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
     223
     224You may also use ``gettext`` binaries you have obtained elsewhere, so long as
     225the ``xgettext --version`` command works properly. Some version 0.14.4 binaries
     226have been found to not support this command. Do not attempt to use Django
     227translation utilities with a ``gettext`` package if the command ``xgettext
     228--version`` entered at a Windows command prompt causes a popup window saying
     229"xgettext.exe has generated errors and will be closed by Windows".
  • docs/topics/index.txt

    diff -r 4755c937c02f 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