Ticket #10260: 10260-i18n-docs-rf-r12336.diff

File 10260-i18n-docs-rf-r12336.diff, 105.5 KB (added by Ramiro Morales, 14 years ago)

Updated to trunk post-r12296, also added a fix for #11793.

  • django/conf/global_settings.py

    diff -r 10ee88612fd8 django/conf/global_settings.py
    a b  
    305305# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
    306306MONTH_DAY_FORMAT = 'F j'
    307307
    308 # Default shortformatting for date objects. See all available format strings here:
     308# Default short formatting for date objects. See all available format strings here:
    309309# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
    310310SHORT_DATE_FORMAT = 'm/d/Y'
    311311
  • new file docs/howto/i18n.txt

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

    diff -r 10ee88612fd8 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 10ee88612fd8 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 10ee88612fd8 docs/ref/settings.txt
    a b  
    883883Default: ``'en-us'``
    884884
    885885A string representing the language code for this installation. This should be in
    886 standard language format. For example, U.S. English is ``"en-us"``. See
    887 :ref:`topics-i18n`.
     886standard :term:`language format<language code>`. For example, U.S. English is
     887``"en-us"``. See :ref:`topics-i18n`.
    888888
    889889.. setting:: LANGUAGE_COOKIE_NAME
    890890
     
    911911
    912912.. _online source: http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py
    913913
    914 The list is a tuple of two-tuples in the format (language code, language
    915 name) -- for example, ``('ja', 'Japanese')``. This specifies which languages
    916 are available for language selection. See :ref:`topics-i18n`.
     914The list is a tuple of two-tuples in the format ``(language code, language
     915name)``, the ``language code`` part should be a
     916:term:`language name<language code>` -- for example, ``('ja', 'Japanese')``.
     917This specifies which languages are available for language selection. See
     918:ref:`topics-i18n`.
    917919
    918920Generally, the default value should suffice. Only set this setting if you want
    919921to restrict language selection to a subset of the Django-provided languages.
     
    948950Default: ``()`` (Empty tuple)
    949951
    950952A tuple of directories where Django looks for translation files.
    951 See :ref:`translations-in-your-own-projects`.
     953See :ref:`using-translations-in-your-own-projects`.
    952954
    953955.. setting:: LOGIN_REDIRECT_URL
    954956
  • docs/releases/1.2.txt

    diff -r 10ee88612fd8 docs/releases/1.2.txt
    a b  
    386386should be updated to use the new :ref:`class-based runners
    387387<topics-testing-test_runner>`.
    388388
     389Technical message IDs
     390---------------------
     391
     392Up to version 1.1 Django used :ref:`technical message IDs<technical-messages>`
     393to provide localizers the possibility to translate date and time formats.  They
     394were translatable :term:`translation string`\s that could be recognized because
     395they were all upper case (for example ``DATETIME_FORMAT``, ``DATE_FORMAT``,
     396``TIME_FORMAT``). They have been deprecated in favor of the new :ref:`Format
     397localization <format-localization>` infrastructure that allows localizers to
     398specify that information in a ``formats.py`` file in the corresponding
     399``django/conf/locale/<locale name>/`` directory.
     400
    389401What's new in Django 1.2
    390402========================
    391403
     
    447459.. code-block:: html+django
    448460
    449461    {% ifnotequal a b %}
    450     ...
     462     ...
    451463    {% endifnotequal %}
    452464
    453 You can now do this::
     465You can now do this:
    454466
    455467.. code-block:: html+django
    456468
    457469    {% if a != b %}
    458     ...
     470     ...
    459471    {% endif %}
    460472
    461473There's really no reason to use ``{% ifequal %}`` or ``{% ifnotequal %}``
  • deleted file docs/topics/i18n.txt

    diff -r 10ee88612fd8 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
    235 plural translation string and the number of objects.
    236 
    237 This function is useful when you need your 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,
    242 irrespective 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
    286     how 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
    365 be 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
    385 with 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 .. admonition:: Gettext utilities
    516 
    517     The ``makemessages`` command (and ``compilemessages`` discussed later) use
    518     commands from the GNU gettext toolset: ``xgetetxt``, ``msgfmt``,
    519     ``msgmerge`` and ``msguniq``.
    520 
    521     .. versionchanged:: 1.2
    522 
    523     The minimum version of the ``gettext`` utilities supported is 0.15.
    524 
    525 To create or update a message file, run this command::
    526 
    527     django-admin.py makemessages -l de
    528 
    529 ...where ``de`` is the language code for the message file you want to create.
    530 The language code, in this case, is in locale format. For example, it's
    531 ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German.
    532 
    533 The script should be run from one of three places:
    534 
    535     * The root directory of your Django project.
    536     * The root directory of your Django app.
    537     * The root ``django`` directory (not a Subversion checkout, but the one
    538       that is linked-to via ``$PYTHONPATH`` or is located somewhere on that
    539       path). This is only relevant when you are creating a translation for
    540       Django itself, see :ref:`contributing-translations`.
    541 
    542 The script runs over your project source tree or your application source tree
    543 and pulls out all strings marked for translation. It creates (or updates) a
    544 message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``
    545 example, the file will be ``locale/de/LC_MESSAGES/django.po``.
    546 
    547 By default ``django-admin.py makemessages`` examines every file that has the
    548 ``.html`` file extension. In case you want to override that default, use the
    549 ``--extension`` or ``-e`` option to specify the file extensions to examine::
    550 
    551     django-admin.py makemessages -l de -e txt
    552 
    553 Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
    554 multiple times::
    555 
    556     django-admin.py makemessages -l=de -e=html,txt -e xml
    557 
    558 When `creating JavaScript translation catalogs`_ you need to use the special
    559 'djangojs' domain, **not** ``-e js``.
    560 
    561 .. admonition:: No gettext?
    562 
    563     If you don't have the ``gettext`` utilities installed, ``django-admin.py
    564     makemessages`` will create empty files. If that's the case, either install
    565     the ``gettext`` utilities or just copy the English message file
    566     (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
    567     point; it's just an empty translation file.
    568 
    569 .. admonition:: Working on Windows?
    570 
    571    If you're using Windows and need to install the GNU gettext utilities so
    572    ``django-admin makemessages`` works see `gettext on Windows`_ for more
    573    information.
    574 
    575 The format of ``.po`` files is straightforward. Each ``.po`` file contains a
    576 small bit of metadata, such as the translation maintainer's contact
    577 information, but the bulk of the file is a list of **messages** -- simple
    578 mappings between translation strings and the actual translated text for the
    579 particular language.
    580 
    581 For example, if your Django app contained a translation string for the text
    582 ``"Welcome to my site."``, like so::
    583 
    584     _("Welcome to my site.")
    585 
    586 ...then ``django-admin.py makemessages`` will have created a ``.po`` file
    587 containing the following snippet -- a message::
    588 
    589     #: path/to/python/module.py:23
    590     msgid "Welcome to my site."
    591     msgstr ""
    592 
    593 A quick explanation:
    594 
    595     * ``msgid`` is the translation string, which appears in the source. Don't
    596       change it.
    597     * ``msgstr`` is where you put the language-specific translation. It starts
    598       out empty, so it's your responsibility to change it. Make sure you keep
    599       the quotes around your translation.
    600     * As a convenience, each message includes, in the form of a comment line
    601       prefixed with ``#`` and located above the ``msgid`` line, the filename
    602       and line number from which the translation string was gleaned.
    603 
    604 Long messages are a special case. There, the first string directly after the
    605 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
    606 written over the next few lines as one string per line. Those strings are
    607 directly concatenated. Don't forget trailing spaces within the strings;
    608 otherwise, they'll be tacked together without whitespace!
    609 
    610 .. admonition:: Mind your charset
    611 
    612     When creating a PO file with your favorite text editor, first edit
    613     the charset line (search for ``"CHARSET"``) and set it to the charset
    614     you'll be using to edit the content. Due to the way the ``gettext`` tools
    615     work internally and because we want to allow non-ASCII source strings in
    616     Django's core and your applications, you **must** use UTF-8 as the encoding
    617     for your PO file. This means that everybody will be using the same
    618     encoding, which is important when Django processes the PO files.
    619 
    620 To reexamine all source code and templates for new translation strings and
    621 update all message files for **all** languages, run this::
    622 
    623     django-admin.py makemessages -a
    624 
    625 Compiling message files
    626 -----------------------
    627 
    628 After you create your message file -- and each time you make changes to it --
    629 you'll need to compile it into a more efficient form, for use by ``gettext``.
    630 Do this with the ``django-admin.py compilemessages`` utility.
    631 
    632 This tool runs over all available ``.po`` files and creates ``.mo`` files,
    633 which are binary files optimized for use by ``gettext``. In the same directory
    634 from which you ran ``django-admin.py makemessages``, run ``django-admin.py
    635 compilemessages`` like this::
    636 
    637    django-admin.py compilemessages
    638 
    639 That's it. Your translations are ready for use.
    640 
    641 .. admonition:: A note to Django veterans
    642 
    643     The old tool ``bin/compile-messages.py`` has been moved to the command
    644     ``django-admin.py compilemessages`` to provide consistency throughout
    645     Django.
    646 
    647 .. admonition:: Working on Windows?
    648 
    649    If you're using Windows and need to install the GNU gettext utilities so
    650    ``django-admin compilemessages`` works see `gettext on Windows`_ for more
    651    information.
    652 
    653 .. _how-django-discovers-language-preference:
    654 
    655 3. How Django discovers language preference
    656 ===========================================
    657 
    658 Once you've prepared your translations -- or, if you just want to use the
    659 translations that come with Django -- you'll just need to activate translation
    660 for your app.
    661 
    662 Behind the scenes, Django has a very flexible model of deciding which language
    663 should be used -- installation-wide, for a particular user, or both.
    664 
    665 To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
    666 Django uses this language as the default translation -- the final attempt if no
    667 other translator finds a translation.
    668 
    669 If all you want to do is run Django with your native language, and a language
    670 file is available for your language, all you need to do is set
    671 ``LANGUAGE_CODE``.
    672 
    673 If you want to let each individual user specify which language he or she
    674 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
    675 selection based on data from the request. It customizes content for each user.
    676 
    677 To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
    678 to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you
    679 should follow these guidelines:
    680 
    681     * Make sure it's one of the first middlewares installed.
    682     * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
    683       makes use of session data.
    684     * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
    685 
    686 For example, your ``MIDDLEWARE_CLASSES`` might look like this::
    687 
    688     MIDDLEWARE_CLASSES = (
    689        'django.contrib.sessions.middleware.SessionMiddleware',
    690        'django.middleware.locale.LocaleMiddleware',
    691        'django.middleware.common.CommonMiddleware',
    692     )
    693 
    694 (For more on middleware, see the :ref:`middleware documentation
    695 <topics-http-middleware>`.)
    696 
    697 ``LocaleMiddleware`` tries to determine the user's language preference by
    698 following this algorithm:
    699 
    700     * First, it looks for a ``django_language`` key in the current user's
    701       session.
    702 
    703     * Failing that, it looks for a cookie.
    704 
    705       .. versionchanged:: 1.0
    706 
    707       In Django version 0.96 and before, the cookie's name is hard-coded to
    708       ``django_language``. In Django 1,0, The cookie name is set by the
    709       ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
    710       ``django_language``.)
    711 
    712     * Failing that, it looks at the ``Accept-Language`` HTTP header. This
    713       header is sent by your browser and tells the server which language(s) you
    714       prefer, in order by priority. Django tries each language in the header
    715       until it finds one with available translations.
    716 
    717     * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
    718 
    719 .. _locale-middleware-notes:
    720 
    721 Notes:
    722 
    723     * In each of these places, the language preference is expected to be in the
    724       standard language format, as a string. For example, Brazilian Portuguese
    725       is ``pt-br``.
    726 
    727     * If a base language is available but the sublanguage specified is not,
    728       Django uses the base language. For example, if a user specifies ``de-at``
    729       (Austrian German) but Django only has ``de`` available, Django uses
    730       ``de``.
    731 
    732     * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
    733       If you want to restrict the language selection to a subset of provided
    734       languages (because your application doesn't provide all those languages),
    735       set ``LANGUAGES`` to a list of languages. For example::
    736 
    737           LANGUAGES = (
    738             ('de', _('German')),
    739             ('en', _('English')),
    740           )
    741 
    742       This example restricts languages that are available for automatic
    743       selection to German and English (and any sublanguage, like de-ch or
    744       en-us).
    745 
    746       .. _LANGUAGES setting: ../settings/#languages
    747 
    748     * If you define a custom ``LANGUAGES`` setting, as explained in the
    749       previous bullet, it's OK to mark the languages as translation strings
    750       -- but use a "dummy" ``ugettext()`` function, not the one in
    751       ``django.utils.translation``. You should *never* import
    752       ``django.utils.translation`` from within your settings file, because that
    753       module in itself depends on the settings, and that would cause a circular
    754       import.
    755 
    756       The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
    757       settings file::
    758 
    759           ugettext = lambda s: s
    760 
    761           LANGUAGES = (
    762               ('de', ugettext('German')),
    763               ('en', ugettext('English')),
    764           )
    765 
    766       With this arrangement, ``django-admin.py makemessages`` will still find
    767       and mark these strings for translation, but the translation won't happen
    768       at runtime -- so you'll have to remember to wrap the languages in the
    769       *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
    770 
    771     * The ``LocaleMiddleware`` can only select languages for which there is a
    772       Django-provided base translation. If you want to provide translations
    773       for your application that aren't already in the set of translations
    774       in Django's source tree, you'll want to provide at least basic
    775       translations for that language. For example, Django uses technical
    776       message IDs to translate date formats and time formats -- so you will
    777       need at least those translations for the system to work correctly.
    778 
    779       A good starting point is to copy the English ``.po`` file and to
    780       translate at least the technical messages -- maybe the validation
    781       messages, too.
    782 
    783       Technical message IDs are easily recognized; they're all upper case. You
    784       don't translate the message ID as with other messages, you provide the
    785       correct local variant on the provided English value. For example, with
    786       ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would
    787       be the format string that you want to use in your language. The format
    788       is identical to the format strings used by the ``now`` template tag.
    789 
    790 Once ``LocaleMiddleware`` determines the user's preference, it makes this
    791 preference available as ``request.LANGUAGE_CODE`` for each
    792 :class:`~django.http.HttpRequest`. Feel free to read this value in your view
    793 code. Here's a simple example::
    794 
    795     def hello_world(request, count):
    796         if request.LANGUAGE_CODE == 'de-at':
    797             return HttpResponse("You prefer to read Austrian German.")
    798         else:
    799             return HttpResponse("You prefer to read another language.")
    800 
    801 Note that, with static (middleware-less) translation, the language is in
    802 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
    803 in ``request.LANGUAGE_CODE``.
    804 
    805 .. _settings file: ../settings/
    806 .. _middleware documentation: ../middleware/
    807 .. _session: ../sessions/
    808 .. _request object: ../request_response/#httprequest-objects
    809 
    810 .. _translations-in-your-own-projects:
    811 
    812 Using translations in your own projects
    813 =======================================
    814 
    815 Django looks for translations by following this algorithm:
    816 
    817     * First, it looks for a ``locale`` directory in the application directory
    818       of the view that's being called. If it finds a translation for the
    819       selected language, the translation will be installed.
    820     * Next, it looks for a ``locale`` directory in the project directory. If it
    821       finds a translation, the translation will be installed.
    822     * Finally, it checks the Django-provided base translation in
    823       ``django/conf/locale``.
    824 
    825 This way, you can write applications that include their own translations, and
    826 you can override base translations in your project path. Or, you can just build
    827 a big project out of several apps and put all translations into one big project
    828 message file. The choice is yours.
    829 
    830 .. note::
    831 
    832     If you're using manually configured settings, as described
    833     :ref:`settings-without-django-settings-module`, the ``locale`` directory in
    834     the project directory will not be examined, since Django loses the ability
    835     to work out the location of the project directory. (Django normally uses
    836     the location of the settings file to determine this, and a settings file
    837     doesn't exist if you're manually configuring your settings.)
    838 
    839 All message file repositories are structured the same way. They are:
    840 
    841     * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
    842     * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
    843     * All paths listed in ``LOCALE_PATHS`` in your settings file are
    844       searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
    845     * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
    846 
    847 To create message files, you use the same ``django-admin.py makemessages``
    848 tool as with the Django message files. You only need to be in the right place
    849 -- in the directory where either the ``conf/locale`` (in case of the source
    850 tree) or the ``locale/`` (in case of app messages or project messages)
    851 directory are located. And you use the same ``django-admin.py
    852 compilemessages`` to produce the binary ``django.mo`` files that are used by
    853 ``gettext``.
    854 
    855 You can also run ``django-admin.py compilemessages
    856 --settings=path.to.settings`` to make the compiler process all the directories
    857 in your ``LOCALE_PATHS`` setting.
    858 
    859 Application message files are a bit complicated to discover -- they need the
    860 ``LocaleMiddleware``. If you don't use the middleware, only the Django message
    861 files and project message files will be processed.
    862 
    863 Finally, you should give some thought to the structure of your translation
    864 files. If your applications need to be delivered to other users and will
    865 be used in other projects, you might want to use app-specific translations.
    866 But using app-specific translations and project translations could produce
    867 weird problems with ``makemessages``: ``makemessages`` will traverse all
    868 directories below the current path and so might put message IDs into the
    869 project message file that are already in application message files.
    870 
    871 The easiest way out is to store applications that are not part of the project
    872 (and so carry their own translations) outside the project tree. That way,
    873 ``django-admin.py makemessages`` on the project level will only translate
    874 strings that are connected to your explicit project and not strings that are
    875 distributed independently.
    876 
    877 The ``set_language`` redirect view
    878 ==================================
    879 
    880 As a convenience, Django comes with a view, ``django.views.i18n.set_language``,
    881 that sets a user's language preference and redirects back to the previous page.
    882 
    883 Activate this view by adding the following line to your URLconf::
    884 
    885     (r'^i18n/', include('django.conf.urls.i18n')),
    886 
    887 (Note that this example makes the view available at ``/i18n/setlang/``.)
    888 
    889 The view expects to be called via the ``POST`` method, with a ``language``
    890 parameter set in request. If session support is enabled, the view
    891 saves the language choice in the user's session. Otherwise, it saves the
    892 language choice in a cookie that is by default named ``django_language``.
    893 (The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
    894 
    895 After setting the language choice, Django redirects the user, following this
    896 algorithm:
    897 
    898     * Django looks for a ``next`` parameter in the ``POST`` data.
    899     * If that doesn't exist, or is empty, Django tries the URL in the
    900       ``Referrer`` header.
    901     * If that's empty -- say, if a user's browser suppresses that header --
    902       then the user will be redirected to ``/`` (the site root) as a fallback.
    903 
    904 Here's example HTML template code:
    905 
    906 .. code-block:: html+django
    907 
    908     <form action="/i18n/setlang/" method="post">
    909     <input name="next" type="hidden" value="/next/page/" />
    910     <select name="language">
    911     {% for lang in LANGUAGES %}
    912     <option value="{{ lang.0 }}">{{ lang.1 }}</option>
    913     {% endfor %}
    914     </select>
    915     <input type="submit" value="Go" />
    916     </form>
    917 
    918 Translations and JavaScript
    919 ===========================
    920 
    921 Adding translations to JavaScript poses some problems:
    922 
    923     * JavaScript code doesn't have access to a ``gettext`` implementation.
    924 
    925     * JavaScript code doesn't have access to .po or .mo files; they need to be
    926       delivered by the server.
    927 
    928     * The translation catalogs for JavaScript should be kept as small as
    929       possible.
    930 
    931 Django provides an integrated solution for these problems: It passes the
    932 translations into JavaScript, so you can call ``gettext``, etc., from within
    933 JavaScript.
    934 
    935 The ``javascript_catalog`` view
    936 -------------------------------
    937 
    938 The main solution to these problems is the ``javascript_catalog`` view, which
    939 sends out a JavaScript code library with functions that mimic the ``gettext``
    940 interface, plus an array of translation strings. Those translation strings are
    941 taken from the application, project or Django core, according to what you
    942 specify in either the info_dict or the URL.
    943 
    944 You hook it up like this::
    945 
    946     js_info_dict = {
    947         'packages': ('your.app.package',),
    948     }
    949 
    950     urlpatterns = patterns('',
    951         (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
    952     )
    953 
    954 Each string in ``packages`` should be in Python dotted-package syntax (the
    955 same format as the strings in ``INSTALLED_APPS``) and should refer to a package
    956 that contains a ``locale`` directory. If you specify multiple packages, all
    957 those catalogs are merged into one catalog. This is useful if you have
    958 JavaScript that uses strings from different applications.
    959 
    960 You can make the view dynamic by putting the packages into the URL pattern::
    961 
    962     urlpatterns = patterns('',
    963         (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
    964     )
    965 
    966 With this, you specify the packages as a list of package names delimited by '+'
    967 signs in the URL. This is especially useful if your pages use code from
    968 different apps and this changes often and you don't want to pull in one big
    969 catalog file. As a security measure, these values can only be either
    970 ``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
    971 
    972 Using the JavaScript translation catalog
    973 ----------------------------------------
    974 
    975 To use the catalog, just pull in the dynamically generated script like this::
    976 
    977     <script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
    978 
    979 This uses reverse URL lookup to find the URL of the JavaScript catalog view.
    980 When the catalog is loaded, your JavaScript code can use the standard
    981 ``gettext`` interface to access it::
    982 
    983     document.write(gettext('this is to be translated'));
    984 
    985 There is also an ``ngettext`` interface::
    986 
    987     var object_cnt = 1 // or 0, or 2, or 3, ...
    988     s = ngettext('literal for the singular case',
    989             'literal for the plural case', object_cnt);
    990 
    991 and even a string interpolation function::
    992 
    993     function interpolate(fmt, obj, named);
    994 
    995 The interpolation syntax is borrowed from Python, so the ``interpolate``
    996 function supports both positional and named interpolation:
    997 
    998     * Positional interpolation: ``obj`` contains a JavaScript Array object
    999       whose elements values are then sequentially interpolated in their
    1000       corresponding ``fmt`` placeholders in the same order they appear.
    1001       For example::
    1002 
    1003         fmts = ngettext('There is %s object. Remaining: %s',
    1004                 'There are %s objects. Remaining: %s', 11);
    1005         s = interpolate(fmts, [11, 20]);
    1006         // s is 'There are 11 objects. Remaining: 20'
    1007 
    1008     * Named interpolation: This mode is selected by passing the optional
    1009       boolean ``named`` parameter as true. ``obj`` contains a JavaScript
    1010       object or associative array. For example::
    1011 
    1012         d = {
    1013             count: 10
    1014             total: 50
    1015         };
    1016 
    1017         fmts = ngettext('Total: %(total)s, there is %(count)s object',
    1018         'there are %(count)s of a total of %(total)s objects', d.count);
    1019         s = interpolate(fmts, d, true);
    1020 
    1021 You shouldn't go over the top with string interpolation, though: this is still
    1022 JavaScript, so the code has to make repeated regular-expression substitutions.
    1023 This isn't as fast as string interpolation in Python, so keep it to those
    1024 cases where you really need it (for example, in conjunction with ``ngettext``
    1025 to produce proper pluralizations).
    1026 
    1027 Creating JavaScript translation catalogs
    1028 ----------------------------------------
    1029 
    1030 You create and update the translation catalogs the same way as the other
    1031 
    1032 Django translation catalogs -- with the ``django-admin.py makemessages`` tool.
    1033 The only difference is you need to provide a ``-d djangojs`` parameter, like
    1034 this::
    1035 
    1036     django-admin.py makemessages -d djangojs -l de
    1037 
    1038 This would create or update the translation catalog for JavaScript for German.
    1039 After updating translation catalogs, just run ``django-admin.py
    1040 compilemessages`` the same way as you do with normal Django translation
    1041 catalogs.
    1042 
    1043 Specialties of Django translation
    1044 ==================================
    1045 
    1046 If you know ``gettext``, you might note these specialties in the way Django
    1047 does translation:
    1048 
    1049     * The string domain is ``django`` or ``djangojs``. This string domain is
    1050       used to differentiate between different programs that store their data
    1051       in a common message-file library (usually ``/usr/share/locale/``). The
    1052       ``django`` domain is used for python and template translation strings
    1053       and is loaded into the global translation catalogs. The ``djangojs``
    1054       domain is only used for JavaScript translation catalogs to make sure
    1055       that those are as small as possible.
    1056     * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
    1057       ``xgettext`` and ``msgfmt``. This is mostly for convenience.
    1058 
    1059 ``gettext`` on Windows
    1060 ======================
    1061 
    1062 This is only needed for people who either want to extract message IDs or
    1063 compile message files (``.po``). Translation work itself just involves editing
    1064 existing files of this type, but if you want to create your own message files,
    1065 or want to test or compile a changed message file, you will need the
    1066 ``gettext`` utilities:
    1067 
    1068     * Download the following zip files from the GNOME servers
    1069       http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
    1070       of its mirrors_
    1071 
    1072       * ``gettext-runtime-X.zip``
    1073       * ``gettext-tools-X.zip``
    1074 
    1075       ``X`` is the version number, we are requiring ``0.15`` or higher.
    1076 
    1077     * Extract the contents of the ``bin\`` directories in both files to the
    1078       same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
    1079 
    1080     * Update the system PATH:
    1081 
    1082       * ``Control Panel > System > Advanced > Environment Variables``
    1083       * In the ``System variables`` list, click ``Path``, click ``Edit``
    1084       * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
    1085         ``Variable value`` field
    1086 
    1087 .. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
    1088 
    1089 You may also use ``gettext`` binaries you have obtained elsewhere, so long as
    1090 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries
    1091 have been found to not support this command. Do not attempt to use Django
    1092 translation utilities with a ``gettext`` package if the command ``xgettext
    1093 --version`` entered at a Windows command prompt causes a popup window saying
    1094 "xgettext.exe has generated errors and will be closed by Windows".
    1095 
    1096 .. _format-localization:
    1097 
    1098 Format localization
    1099 ===================
    1100 
    1101 Django's formatting system is disabled by default. To enable it, it's necessay
    1102 to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
    1103 
    1104 When using Django's formatting system, dates and numbers on templates will be
    1105 displayed using the format specified for the current locale. Two users
    1106 accessing the same content, but in different language, will see date and
    1107 number fields formatted in different ways, depending on the format for their
    1108 current locale.
    1109 
    1110 Django will also use localized formats when parsing data in forms. That means
    1111 Django uses different formats for different locales when guessing the format
    1112 used by the user when inputting data on forms. Note that Django uses different
    1113 formats for displaying data, and for parsing it.
    1114 
    1115 Creating custom format files
    1116 ----------------------------
    1117 
    1118 Django provides format definitions for many locales, but sometimes you might
    1119 want to create your own, because a format files doesn't exist for your locale,
    1120 or because you want to overwrite some of the values.
    1121 
    1122 To use custom formats, first thing to do, is to specify the path where you'll
    1123 place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH`
    1124 setting to the the path (in the format ``'foo.bar.baz``) where format files
    1125 will exists.
    1126 
    1127 Files are not placed directly in this directory, but in a directory named as
    1128 the locale, and must be named ``formats.py``.
    1129 
    1130 To customize the English formats, a structure like this would be needed::
    1131 
    1132     mysite/
    1133         formats/
    1134             __init__.py
    1135             en/
    1136                 __init__.py
    1137                 formats.py
    1138 
    1139 where :file:`formats.py` contains custom format definitions. For example::
    1140 
    1141     THOUSAND_SEPARATOR = ' '
    1142 
    1143 to use a space as a thousand separator, instead of the default for English,
    1144 a comma.
  • new file docs/topics/i18n/deployment.txt

    diff -r 10ee88612fd8 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 :term:`language format<language code>`, as a string. For example,
     106      Brazilian Portuguese 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``.
     192
     193In all cases the name of the directory containing the translation is expected to
     194be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
     195etc.
  • new file docs/topics/i18n/index.txt

    diff -r 10ee88612fd8 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
     46Glossary
     47========
     48
     49First lets define some terms that will help us to handle a common language:
     50
     51.. glossary::
     52
     53    locale name
     54      A locale name, either a language specification of the form ``ll`` or a
     55      combined language and country specification of the form ``ll_CC``.
     56      Examples: ``it``, ``de_AT``, ``es``, ``pt_BR``. Note the underscore in
     57      some of them and the case of the part located to its right.
     58
     59    language code
     60      Represents the name of a language. Browsers send the names of the
     61      languages they accept in the ``Accept-Language`` HTTP header using this
     62      format. Examples: ``it``, ``de-at``, ``es``, ``pt-br``. Note the ``-``
     63      separator.
     64
     65    message file
     66      A message file is a plain-text file, representing a single language, that
     67      contains all available :term:`translation string`\s and how they should be
     68      represented in the given language. Message files have a ``.po`` file
     69      extension.
     70
     71    translation string
     72      A literal that can be translated.
     73
     74.. _specialties-of-django-i18n:
     75
     76Specialties of Django translation
     77==================================
     78
     79Django's translation machinery uses the standard ``gettext`` module that comes
     80with Python. If you know ``gettext``, you might note these specialties in the
     81way Django does translation:
     82
     83    * The string domain is ``django`` or ``djangojs``. This string domain is
     84      used to differentiate between different programs that store their data
     85      in a common message-file library (usually ``/usr/share/locale/``). The
     86      ``django`` domain is used for python and template translation strings
     87      and is loaded into the global translation catalogs. The ``djangojs``
     88      domain is only used for JavaScript translation catalogs to make sure
     89      that those are as small as possible.
     90    * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
     91      ``xgettext`` and ``msgfmt``. This is mostly for convenience.
     92
     93.. _technical-messages:
     94
     95Django technical message IDs
     96----------------------------
     97
     98.. versionchanged:: 1.2
     99    Starting with Django 1.2, technical message IDs are being replaced by :ref:`format-localization`
     100
     101Django uses technical message IDs to translate date formats and time formats.
     102Technical message IDs are :term:`translation string`\s and can be easily
     103recognized; they're all upper case. You don't translate the message ID as with
     104other translation strings, you provide the correct local variant on the provided
     105English value.  The format is identical to the format strings used by the
     106``now`` template tag.
     107
     108For example, with ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``),
     109this would be the format string that you want to use in your language. A Django
     110contributor localizing it to Spanish probably would provide a ``"j N Y P"``
     111"translation" for it in the relevant ``django.po`` file::
     112
     113    msgid "DATETIME_FORMAT"
     114    msgstr "j N Y P"
  • new file docs/topics/i18n/internationalization.txt

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

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

    diff -r 10ee88612fd8 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