Ticket #10260: 10260-post-r11964.2.diff

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

More enhancements, includes fix for #12449

  • django/conf/global_settings.py

    diff -r 8a4e070b280a django/conf/global_settings.py
    a b  
    297297# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
    298298MONTH_DAY_FORMAT = 'F j'
    299299
    300 # Default shortformatting for date objects. See all available format strings here:
     300# Default short formatting for date objects. See all available format strings here:
    301301# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
    302302SHORT_DATE_FORMAT = 'm/d/Y'
    303303
  • new file docs/howto/i18n.txt

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

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

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

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

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

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

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

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

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

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