Ticket #10260: 10260-i18n-docs-rf-r12336.diff
File 10260-i18n-docs-rf-r12336.diff, 105.5 KB (added by , 15 years ago) |
---|
-
django/conf/global_settings.py
diff -r 10ee88612fd8 django/conf/global_settings.py
a b 305 305 # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now 306 306 MONTH_DAY_FORMAT = 'F j' 307 307 308 # Default short formatting for date objects. See all available format strings here:308 # Default short formatting for date objects. See all available format strings here: 309 309 # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now 310 310 SHORT_DATE_FORMAT = 'm/d/Y' 311 311 -
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 =============================================== 6 Using internationalization in your own projects 7 =============================================== 8 9 At 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 19 In all cases the name of the directory containing the translation is expected to 20 be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``, 21 etc. 22 23 This way, you can write applications that include their own translations, and 24 you can override base translations in your project path. Or, you can just build 25 a big project out of several apps and put all translations into one big project 26 message 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 37 All 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 45 To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>` 46 tool. You only need to be in the same directory where the ``locale/`` directory 47 is located. And you use :djadmin:`django-admin.py compilemessages <compilemessages>` 48 to produce the binary ``.mo`` files that are used by ``gettext``. Read the 49 :ref:`topics-i18n-localization` document for more details. 50 51 You can also run ``django-admin.py compilemessages --settings=path.to.settings`` 52 to make the compiler process all the directories in your :setting:`LOCALE_PATHS` 53 setting. 54 55 Application message files are a bit complicated to discover -- they need the 56 :class:`~django.middleware.locale.LocaleMiddleware`. If you don't use the 57 middleware, only the Django message files and project message files will be 58 installed and available at runtime. 59 60 Finally, you should give some thought to the structure of your translation 61 files. If your applications need to be delivered to other users and will 62 be used in other projects, you might want to use app-specific translations. 63 But using app-specific translations and project translations could produce 64 weird problems with ``makemessages``: It will traverse all directories below 65 the current path and so might put message IDs into the project message file 66 that are already in application message files. 67 68 The 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 71 strings that are connected to your explicit project and not strings that are 72 distributed independently. -
docs/howto/index.txt
diff -r 10ee88612fd8 docs/howto/index.txt
a b 20 20 deployment/index 21 21 error-reporting 22 22 initial-data 23 i18n 23 24 jython 24 25 legacy-databases 25 26 outputting-csv -
docs/internals/contributing.txt
diff -r 10ee88612fd8 docs/internals/contributing.txt
a b 402 402 403 403 * Join the `Django i18n mailing list`_ and introduce yourself. 404 404 405 * Make sure you read the notes about :ref:`specialties-of-django-i18n`. 406 405 407 * 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. 409 412 410 413 The script runs over the entire Django source tree and pulls out all 411 414 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 be413 ``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``). 414 417 415 418 * Make sure that ``django-admin.py compilemessages -l <lang>`` runs without 416 419 producing any warnings. … … 419 422 ``-d djangojs`` command line option to the ``django-admin.py`` 420 423 invocations). 421 424 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. 423 430 424 431 * Open a ticket in Django's ticket system, set its ``Component`` field to 425 432 ``Translations``, and attach the patch to it. -
docs/ref/settings.txt
diff -r 10ee88612fd8 docs/ref/settings.txt
a b 883 883 Default: ``'en-us'`` 884 884 885 885 A string representing the language code for this installation. This should be in 886 standard language format. For example, U.S. English is ``"en-us"``. See887 :ref:`topics-i18n`.886 standard :term:`language format<language code>`. For example, U.S. English is 887 ``"en-us"``. See :ref:`topics-i18n`. 888 888 889 889 .. setting:: LANGUAGE_COOKIE_NAME 890 890 … … 911 911 912 912 .. _online source: http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py 913 913 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`. 914 The list is a tuple of two-tuples in the format ``(language code, language 915 name)``, the ``language code`` part should be a 916 :term:`language name<language code>` -- for example, ``('ja', 'Japanese')``. 917 This specifies which languages are available for language selection. See 918 :ref:`topics-i18n`. 917 919 918 920 Generally, the default value should suffice. Only set this setting if you want 919 921 to restrict language selection to a subset of the Django-provided languages. … … 948 950 Default: ``()`` (Empty tuple) 949 951 950 952 A tuple of directories where Django looks for translation files. 951 See :ref:` translations-in-your-own-projects`.953 See :ref:`using-translations-in-your-own-projects`. 952 954 953 955 .. setting:: LOGIN_REDIRECT_URL 954 956 -
docs/releases/1.2.txt
diff -r 10ee88612fd8 docs/releases/1.2.txt
a b 386 386 should be updated to use the new :ref:`class-based runners 387 387 <topics-testing-test_runner>`. 388 388 389 Technical message IDs 390 --------------------- 391 392 Up to version 1.1 Django used :ref:`technical message IDs<technical-messages>` 393 to provide localizers the possibility to translate date and time formats. They 394 were translatable :term:`translation string`\s that could be recognized because 395 they were all upper case (for example ``DATETIME_FORMAT``, ``DATE_FORMAT``, 396 ``TIME_FORMAT``). They have been deprecated in favor of the new :ref:`Format 397 localization <format-localization>` infrastructure that allows localizers to 398 specify that information in a ``formats.py`` file in the corresponding 399 ``django/conf/locale/<locale name>/`` directory. 400 389 401 What's new in Django 1.2 390 402 ======================== 391 403 … … 447 459 .. code-block:: html+django 448 460 449 461 {% ifnotequal a b %} 450 ...462 ... 451 463 {% endifnotequal %} 452 464 453 You can now do this: :465 You can now do this: 454 466 455 467 .. code-block:: html+django 456 468 457 469 {% if a != b %} 458 ...470 ... 459 471 {% endif %} 460 472 461 473 There'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 Internationalization5 ====================6 7 Django has full support for internationalization of text in code and8 templates, and format localization of dates and numbers. Here's how it works.9 10 Overview11 ========12 13 The goal of internationalization is to allow a single Web application to offer14 its content and functionality in multiple languages and locales.15 16 For text translation, you, the Django developer, can accomplish this goal by17 adding a minimal amount of hooks to your Python code and templates. These hooks18 are called **translation strings**. They tell Django: "This text should be19 translated into the end user's language, if a translation for this text is20 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 apps28 should be translatable.29 * It uses these hooks to translate Web apps for particular users according30 to their language preferences.31 32 For format localization, it's just necessary to set33 :setting:`USE_L10N = True <USE_L10N>` in your settings file. If34 :setting:`USE_L10N` is set to ``True``, Django will display35 numbers and dates in the format of the current locale. That includes field36 representation on templates, and allowed input formats on the admin.37 38 If you don't need internationalization in your app39 ==================================================40 41 Django's internationalization hooks are on by default, and that means there's a42 bit of i18n-related overhead in certain places of the framework. If you don't43 use internationalization, you should take the two seconds to set44 :setting:`USE_I18N = False <USE_I18N>` in your settings file. If45 :setting:`USE_I18N` is set to ``False``, then Django will make some46 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 steps52 ================================================53 54 1. Embed translation strings in your Python code and templates.55 2. Get translations for those strings, in whichever languages you want to56 support.57 3. Activate the locale middleware in your Django settings.58 59 .. admonition:: Behind the scenes60 61 Django's translation machinery uses the standard ``gettext`` module that62 comes with Python.63 64 1. How to specify translation strings65 =====================================66 67 Translation strings specify "This text should be translated." These strings can68 appear in your Python code and templates. It's your responsibility to mark69 translatable strings; the system can only translate strings it knows about.70 71 In Python code72 --------------73 74 Standard translation75 ~~~~~~~~~~~~~~~~~~~~76 77 Specify a translation string by using the function ``ugettext()``. It's78 convention to import this as a shorter alias, ``_``, to save typing.79 80 .. note::81 Python's standard library ``gettext`` module installs ``_()`` into the82 global namespace, as an alias for ``gettext()``. In Django, we have chosen83 not to follow this practice, for a couple of reasons:84 85 1. For international character set (Unicode) support, ``ugettext()`` is86 more useful than ``gettext()``. Sometimes, you should be using87 ``ugettext_lazy()`` as the default translation method for a particular88 file. Without ``_()`` in the global namespace, the developer has to89 think about which is the most appropriate translation function.90 91 2. The underscore character (``_``) is used to represent "the previous92 result" in Python's interactive shell and doctest tests. Installing a93 global ``_()`` function causes interference. Explicitly importing94 ``ugettext()`` as ``_()`` avoids this problem.95 96 .. highlightlang:: python97 98 In this example, the text ``"Welcome to my site."`` is marked as a translation99 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 is108 identical to the previous one::109 110 from django.utils.translation import ugettext111 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 previous117 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 two132 examples, is that Django's translation-string-detecting utility,133 ``django-admin.py makemessages``, won't be able to find these strings. More on134 ``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 placeholder144 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 the146 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 you150 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-op154 ~~~~~~~~~~~~~~~~~~~~~~~~155 156 Use the function ``django.utils.translation.ugettext_noop()`` to mark a string157 as a translation string without translating it. The string is later translated158 from a variable.159 160 Use this if you have constant strings that should be stored in the source161 language because they are exchanged over systems or users -- such as strings in162 a database -- but should be translated at the last possible point in time, such163 as when the string is presented to the user.164 165 .. _lazy-translations:166 167 Lazy translation168 ~~~~~~~~~~~~~~~~169 170 Use the function ``django.utils.translation.ugettext_lazy()`` to translate171 strings lazily -- when the value is accessed rather than when the172 ``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_lazy177 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 string183 is used in a string context, such as template rendering on the Django admin184 site.185 186 The result of a ``ugettext_lazy()`` call can be used wherever you would use a187 unicode string (an object with type ``unicode``) in Python. If you try to use188 it where a bytestring (a ``str`` object) is expected, things will not work as189 expected, since a ``ugettext_lazy()`` object doesn't know how to convert190 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 object197 # 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 ``"hello201 <django.utils.functional...>"``, you have tried to insert the result of202 ``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 as205 ``_`` (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, they214 won't be translated in the admin interface). This means writing explicit215 ``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,216 though, rather than relying on Django's default determination of217 ``verbose_name`` and ``verbose_name_plural`` by looking at the model's class218 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 Pluralization229 ~~~~~~~~~~~~~230 231 Use the function ``django.utils.translation.ungettext()`` to specify pluralized232 messages.233 234 ``ungettext`` takes three arguments: the singular translation string, the235 plural translation string and the number of objects.236 237 This function is useful when you need your Django application to be localizable238 to languages where the number and complexity of `plural forms239 <http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is240 greater than the two forms used in English ('object' for the singular and241 '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 ungettext247 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 as254 the ``count`` variable.255 256 Lets see a slightly more complex usage example::257 258 from django.utils.translation import ungettext259 260 count = Report.objects.count()261 if count == 1:262 name = Report._meta.verbose_name263 else:264 name = Report._meta.verbose_name_plural265 266 text = ungettext(267 'There is %(count)d %(name)s available.',268 'There are %(count)d %(name)s available.',269 count270 ) % {271 'count': count,272 'name': name273 }274 275 Here we reuse localizable, hopefully already translated literals (contained in276 the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for277 other parts of the sentence so all of it is consistently based on the278 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 every285 extrapolated variable included in the literal. In the example above note286 how we used the ``name`` Python variable in both translation strings. This287 example would fail::288 289 from django.utils.translation import ungettext290 from myapp.models import Report291 292 count = Report.objects.count()293 d = {294 'count': count,295 'name': Report._meta.verbose_name296 'plural_name': Report._meta.verbose_name_plural297 }298 text = ungettext(299 'There is %(count)d %(name)s available.',300 'There are %(count)d %(plural_name)s available.',301 count302 ) % d303 304 You would get a ``a format specification for argument 'name', as in305 'msgstr[0]', doesn't exist in 'msgid'`` error when running306 ``django-admin.py compilemessages`` or a ``KeyError`` Python exception at307 runtime.308 309 In template code310 ----------------311 312 .. highlightlang:: html+django313 314 Translations in :ref:`Django templates <topics-templates>` uses two template315 tags and a slightly different syntax than in Python code. To give your template316 access to these tags, put ``{% load i18n %}`` toward the top of your template.317 318 The ``{% trans %}`` template tag translates either a constant string319 (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 the325 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 ``{% trans333 %}``. If your translations require strings with variables (placeholders), use334 ``{% blocktrans %}``::335 336 {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}337 338 To translate a template expression -- say, using template filters -- you need339 to bind the expression to a local variable for use within the translation340 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 the354 ``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and355 ``{% 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 local364 variables apart from the counter value that selects the translated literal to365 be used, have in mind that the ``blocktrans`` construct is internally converted366 to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext367 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 the372 language code and the second is the language name (translated into the373 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 a380 right-to-left language, e.g.: Hebrew, Arabic. If False it's a381 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 values385 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 accepts394 constant strings. In those cases, just use ``_()`` syntax to specify a395 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-translated400 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 string404 ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The405 translated string will need to contain the comma so that the filter406 parsing code knows how to split up the arguments. For example, a German407 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 objects413 -------------------------------------414 415 .. highlightlang:: python416 417 Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models418 and utility functions is a common operation. When you're working with these419 objects elsewhere in your code, you should ensure that you don't accidentally420 convert them to strings, because they should be converted as late as possible421 (so that the correct locale is in effect). This necessitates the use of a422 couple of helper functions.423 424 Joining strings: string_concat()425 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~426 427 Standard Python string joins (``''.join([...])``) will not work on lists428 containing lazy translation objects. Instead, you can use429 ``django.utils.translation.string_concat()``, which creates a lazy object that430 concatenates its contents *and* converts them to strings only when the result431 is included in a string. For example::432 433 from django.utils.translation import string_concat434 ...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 to440 strings when ``result`` itself is used in a string (usually at template441 rendering time).442 443 The allow_lazy() decorator444 ~~~~~~~~~~~~~~~~~~~~~~~~~~445 446 Django offers many utility functions (particularly in ``django.utils``) that447 take a string as their first argument and do something to that string. These448 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'll451 face the problem of what to do when the first argument is a lazy translation452 object. You don't want to convert it to a string immediately, because you might453 be using this function outside of a view (and hence the current thread's locale454 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 lazy458 translation as the first argument, the function evaluation is delayed until it459 needs to be converted to a string.460 461 For example::462 463 from django.utils.functional import allow_lazy464 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 the472 original function can return. Usually, it's enough to include ``unicode`` here473 and ensure that your function returns only Unicode strings.474 475 Using this decorator means you can write your function and assume that the476 input is a proper string, then add support for lazy translation objects at the477 end.478 479 .. _how-to-create-language-files:480 481 2. How to create language files482 ===============================483 484 Once you've tagged your strings for later translation, you need to write (or485 obtain) the language translations themselves. Here's how that works.486 487 .. admonition:: Locale restrictions488 489 Django does not support localizing your application into a locale for490 which Django itself has not been translated. In this case, it will ignore491 your translation files. If you were to try this and Django supported it,492 you would inevitably see a mixture of translated strings (from your493 application) and English strings (from Django itself). If you want to494 support a locale for your application that is not already part of495 Django, you'll need to make at least a minimal translation of the Django496 core. See the relevant :ref:`LocaleMiddleware note<locale-middleware-notes>`497 for more details.498 499 Message files500 -------------501 502 The first step is to create a **message file** for a new language. A message503 file is a plain-text file, representing a single language, that contains all504 available translation strings and how they should be represented in the given505 language. Message files have a ``.po`` file extension.506 507 Django comes with a tool, ``django-admin.py makemessages``, that automates the508 creation and upkeep of these files.509 510 .. admonition:: A note to Django veterans511 512 The old tool ``bin/make-messages.py`` has been moved to the command513 ``django-admin.py makemessages`` to provide consistency throughout Django.514 515 .. admonition:: Gettext utilities516 517 The ``makemessages`` command (and ``compilemessages`` discussed later) use518 commands from the GNU gettext toolset: ``xgetetxt``, ``msgfmt``,519 ``msgmerge`` and ``msguniq``.520 521 .. versionchanged:: 1.2522 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 de528 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's531 ``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 one538 that is linked-to via ``$PYTHONPATH`` or is located somewhere on that539 path). This is only relevant when you are creating a translation for540 Django itself, see :ref:`contributing-translations`.541 542 The script runs over your project source tree or your application source tree543 and pulls out all strings marked for translation. It creates (or updates) a544 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 the548 ``.html`` file extension. In case you want to override that default, use the549 ``--extension`` or ``-e`` option to specify the file extensions to examine::550 551 django-admin.py makemessages -l de -e txt552 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 xml557 558 When `creating JavaScript translation catalogs`_ you need to use the special559 'djangojs' domain, **not** ``-e js``.560 561 .. admonition:: No gettext?562 563 If you don't have the ``gettext`` utilities installed, ``django-admin.py564 makemessages`` will create empty files. If that's the case, either install565 the ``gettext`` utilities or just copy the English message file566 (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting567 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 so572 ``django-admin makemessages`` works see `gettext on Windows`_ for more573 information.574 575 The format of ``.po`` files is straightforward. Each ``.po`` file contains a576 small bit of metadata, such as the translation maintainer's contact577 information, but the bulk of the file is a list of **messages** -- simple578 mappings between translation strings and the actual translated text for the579 particular language.580 581 For example, if your Django app contained a translation string for the text582 ``"Welcome to my site."``, like so::583 584 _("Welcome to my site.")585 586 ...then ``django-admin.py makemessages`` will have created a ``.po`` file587 containing the following snippet -- a message::588 589 #: path/to/python/module.py:23590 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't596 change it.597 * ``msgstr`` is where you put the language-specific translation. It starts598 out empty, so it's your responsibility to change it. Make sure you keep599 the quotes around your translation.600 * As a convenience, each message includes, in the form of a comment line601 prefixed with ``#`` and located above the ``msgid`` line, the filename602 and line number from which the translation string was gleaned.603 604 Long messages are a special case. There, the first string directly after the605 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be606 written over the next few lines as one string per line. Those strings are607 directly concatenated. Don't forget trailing spaces within the strings;608 otherwise, they'll be tacked together without whitespace!609 610 .. admonition:: Mind your charset611 612 When creating a PO file with your favorite text editor, first edit613 the charset line (search for ``"CHARSET"``) and set it to the charset614 you'll be using to edit the content. Due to the way the ``gettext`` tools615 work internally and because we want to allow non-ASCII source strings in616 Django's core and your applications, you **must** use UTF-8 as the encoding617 for your PO file. This means that everybody will be using the same618 encoding, which is important when Django processes the PO files.619 620 To reexamine all source code and templates for new translation strings and621 update all message files for **all** languages, run this::622 623 django-admin.py makemessages -a624 625 Compiling message files626 -----------------------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 directory634 from which you ran ``django-admin.py makemessages``, run ``django-admin.py635 compilemessages`` like this::636 637 django-admin.py compilemessages638 639 That's it. Your translations are ready for use.640 641 .. admonition:: A note to Django veterans642 643 The old tool ``bin/compile-messages.py`` has been moved to the command644 ``django-admin.py compilemessages`` to provide consistency throughout645 Django.646 647 .. admonition:: Working on Windows?648 649 If you're using Windows and need to install the GNU gettext utilities so650 ``django-admin compilemessages`` works see `gettext on Windows`_ for more651 information.652 653 .. _how-django-discovers-language-preference:654 655 3. How Django discovers language preference656 ===========================================657 658 Once you've prepared your translations -- or, if you just want to use the659 translations that come with Django -- you'll just need to activate translation660 for your app.661 662 Behind the scenes, Django has a very flexible model of deciding which language663 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 no667 other translator finds a translation.668 669 If all you want to do is run Django with your native language, and a language670 file is available for your language, all you need to do is set671 ``LANGUAGE_CODE``.672 673 If you want to let each individual user specify which language he or she674 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language675 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, you679 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 documentation695 <topics-http-middleware>`.)696 697 ``LocaleMiddleware`` tries to determine the user's language preference by698 following this algorithm:699 700 * First, it looks for a ``django_language`` key in the current user's701 session.702 703 * Failing that, it looks for a cookie.704 705 .. versionchanged:: 1.0706 707 In Django version 0.96 and before, the cookie's name is hard-coded to708 ``django_language``. In Django 1,0, The cookie name is set by the709 ``LANGUAGE_COOKIE_NAME`` setting. (The default name is710 ``django_language``.)711 712 * Failing that, it looks at the ``Accept-Language`` HTTP header. This713 header is sent by your browser and tells the server which language(s) you714 prefer, in order by priority. Django tries each language in the header715 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 the724 standard language format, as a string. For example, Brazilian Portuguese725 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 uses730 ``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 provided734 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 automatic743 selection to German and English (and any sublanguage, like de-ch or744 en-us).745 746 .. _LANGUAGES setting: ../settings/#languages747 748 * If you define a custom ``LANGUAGES`` setting, as explained in the749 previous bullet, it's OK to mark the languages as translation strings750 -- but use a "dummy" ``ugettext()`` function, not the one in751 ``django.utils.translation``. You should *never* import752 ``django.utils.translation`` from within your settings file, because that753 module in itself depends on the settings, and that would cause a circular754 import.755 756 The solution is to use a "dummy" ``ugettext()`` function. Here's a sample757 settings file::758 759 ugettext = lambda s: s760 761 LANGUAGES = (762 ('de', ugettext('German')),763 ('en', ugettext('English')),764 )765 766 With this arrangement, ``django-admin.py makemessages`` will still find767 and mark these strings for translation, but the translation won't happen768 at runtime -- so you'll have to remember to wrap the languages in the769 *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.770 771 * The ``LocaleMiddleware`` can only select languages for which there is a772 Django-provided base translation. If you want to provide translations773 for your application that aren't already in the set of translations774 in Django's source tree, you'll want to provide at least basic775 translations for that language. For example, Django uses technical776 message IDs to translate date formats and time formats -- so you will777 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 to780 translate at least the technical messages -- maybe the validation781 messages, too.782 783 Technical message IDs are easily recognized; they're all upper case. You784 don't translate the message ID as with other messages, you provide the785 correct local variant on the provided English value. For example, with786 ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would787 be the format string that you want to use in your language. The format788 is identical to the format strings used by the ``now`` template tag.789 790 Once ``LocaleMiddleware`` determines the user's preference, it makes this791 preference available as ``request.LANGUAGE_CODE`` for each792 :class:`~django.http.HttpRequest`. Feel free to read this value in your view793 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 in802 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's803 in ``request.LANGUAGE_CODE``.804 805 .. _settings file: ../settings/806 .. _middleware documentation: ../middleware/807 .. _session: ../sessions/808 .. _request object: ../request_response/#httprequest-objects809 810 .. _translations-in-your-own-projects:811 812 Using translations in your own projects813 =======================================814 815 Django looks for translations by following this algorithm:816 817 * First, it looks for a ``locale`` directory in the application directory818 of the view that's being called. If it finds a translation for the819 selected language, the translation will be installed.820 * Next, it looks for a ``locale`` directory in the project directory. If it821 finds a translation, the translation will be installed.822 * Finally, it checks the Django-provided base translation in823 ``django/conf/locale``.824 825 This way, you can write applications that include their own translations, and826 you can override base translations in your project path. Or, you can just build827 a big project out of several apps and put all translations into one big project828 message file. The choice is yours.829 830 .. note::831 832 If you're using manually configured settings, as described833 :ref:`settings-without-django-settings-module`, the ``locale`` directory in834 the project directory will not be examined, since Django loses the ability835 to work out the location of the project directory. (Django normally uses836 the location of the settings file to determine this, and a settings file837 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 are844 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 place849 -- in the directory where either the ``conf/locale`` (in case of the source850 tree) or the ``locale/`` (in case of app messages or project messages)851 directory are located. And you use the same ``django-admin.py852 compilemessages`` to produce the binary ``django.mo`` files that are used by853 ``gettext``.854 855 You can also run ``django-admin.py compilemessages856 --settings=path.to.settings`` to make the compiler process all the directories857 in your ``LOCALE_PATHS`` setting.858 859 Application message files are a bit complicated to discover -- they need the860 ``LocaleMiddleware``. If you don't use the middleware, only the Django message861 files and project message files will be processed.862 863 Finally, you should give some thought to the structure of your translation864 files. If your applications need to be delivered to other users and will865 be used in other projects, you might want to use app-specific translations.866 But using app-specific translations and project translations could produce867 weird problems with ``makemessages``: ``makemessages`` will traverse all868 directories below the current path and so might put message IDs into the869 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 project872 (and so carry their own translations) outside the project tree. That way,873 ``django-admin.py makemessages`` on the project level will only translate874 strings that are connected to your explicit project and not strings that are875 distributed independently.876 877 The ``set_language`` redirect view878 ==================================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 view891 saves the language choice in the user's session. Otherwise, it saves the892 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 this896 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 the900 ``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+django907 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 JavaScript919 ===========================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 be926 delivered by the server.927 928 * The translation catalogs for JavaScript should be kept as small as929 possible.930 931 Django provides an integrated solution for these problems: It passes the932 translations into JavaScript, so you can call ``gettext``, etc., from within933 JavaScript.934 935 The ``javascript_catalog`` view936 -------------------------------937 938 The main solution to these problems is the ``javascript_catalog`` view, which939 sends out a JavaScript code library with functions that mimic the ``gettext``940 interface, plus an array of translation strings. Those translation strings are941 taken from the application, project or Django core, according to what you942 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 (the955 same format as the strings in ``INSTALLED_APPS``) and should refer to a package956 that contains a ``locale`` directory. If you specify multiple packages, all957 those catalogs are merged into one catalog. This is useful if you have958 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 from968 different apps and this changes often and you don't want to pull in one big969 catalog file. As a security measure, these values can only be either970 ``django.conf`` or any package from the ``INSTALLED_APPS`` setting.971 972 Using the JavaScript translation catalog973 ----------------------------------------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 standard981 ``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 object999 whose elements values are then sequentially interpolated in their1000 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 optional1009 boolean ``named`` parameter as true. ``obj`` contains a JavaScript1010 object or associative array. For example::1011 1012 d = {1013 count: 101014 total: 501015 };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 still1022 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 those1024 cases where you really need it (for example, in conjunction with ``ngettext``1025 to produce proper pluralizations).1026 1027 Creating JavaScript translation catalogs1028 ----------------------------------------1029 1030 You create and update the translation catalogs the same way as the other1031 1032 Django translation catalogs -- with the ``django-admin.py makemessages`` tool.1033 The only difference is you need to provide a ``-d djangojs`` parameter, like1034 this::1035 1036 django-admin.py makemessages -d djangojs -l de1037 1038 This would create or update the translation catalog for JavaScript for German.1039 After updating translation catalogs, just run ``django-admin.py1040 compilemessages`` the same way as you do with normal Django translation1041 catalogs.1042 1043 Specialties of Django translation1044 ==================================1045 1046 If you know ``gettext``, you might note these specialties in the way Django1047 does translation:1048 1049 * The string domain is ``django`` or ``djangojs``. This string domain is1050 used to differentiate between different programs that store their data1051 in a common message-file library (usually ``/usr/share/locale/``). The1052 ``django`` domain is used for python and template translation strings1053 and is loaded into the global translation catalogs. The ``djangojs``1054 domain is only used for JavaScript translation catalogs to make sure1055 that those are as small as possible.1056 * Django doesn't use ``xgettext`` alone. It uses Python wrappers around1057 ``xgettext`` and ``msgfmt``. This is mostly for convenience.1058 1059 ``gettext`` on Windows1060 ======================1061 1062 This is only needed for people who either want to extract message IDs or1063 compile message files (``.po``). Translation work itself just involves editing1064 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 the1066 ``gettext`` utilities:1067 1068 * Download the following zip files from the GNOME servers1069 http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one1070 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 the1078 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 the1085 ``Variable value`` field1086 1087 .. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS1088 1089 You may also use ``gettext`` binaries you have obtained elsewhere, so long as1090 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries1091 have been found to not support this command. Do not attempt to use Django1092 translation utilities with a ``gettext`` package if the command ``xgettext1093 --version`` entered at a Windows command prompt causes a popup window saying1094 "xgettext.exe has generated errors and will be closed by Windows".1095 1096 .. _format-localization:1097 1098 Format localization1099 ===================1100 1101 Django's formatting system is disabled by default. To enable it, it's necessay1102 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 be1105 displayed using the format specified for the current locale. Two users1106 accessing the same content, but in different language, will see date and1107 number fields formatted in different ways, depending on the format for their1108 current locale.1109 1110 Django will also use localized formats when parsing data in forms. That means1111 Django uses different formats for different locales when guessing the format1112 used by the user when inputting data on forms. Note that Django uses different1113 formats for displaying data, and for parsing it.1114 1115 Creating custom format files1116 ----------------------------1117 1118 Django provides format definitions for many locales, but sometimes you might1119 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'll1123 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 files1125 will exists.1126 1127 Files are not placed directly in this directory, but in a directory named as1128 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__.py1135 en/1136 __init__.py1137 formats.py1138 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 ============================================= 4 Deployment of Django application translations 5 ============================================= 6 7 If you don't need internationalization in your app 8 ================================================== 9 10 Django's internationalization hooks are on by default, and that means there's a 11 bit of i18n-related overhead in certain places of the framework. If you don't 12 use 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 15 optimizations so as not to load the internationalization machinery. 16 17 You'll probably also want to remove ``'django.core.context_processors.i18n'`` 18 from 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 32 If you do need internationalization 33 =================================== 34 35 .. _how-django-discovers-language-preference: 36 37 How Django discovers language preference 38 ---------------------------------------- 39 40 Once you've prepared your translations -- or, if you just want to use the 41 translations that come with Django -- you'll just need to activate translation 42 for your app. 43 44 Behind the scenes, Django has a very flexible model of deciding which language 45 should be used -- installation-wide, for a particular user, or both. 46 47 To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`. 48 Django uses this language as the default translation -- the final attempt if no 49 other translator finds a translation. 50 51 If all you want to do is run Django with your native language, and a language 52 file is available for it, all you need to do is set ``LANGUAGE_CODE``. 53 54 If you want to let each individual user specify which language he or she 55 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language 56 selection based on data from the request. It customizes content for each user. 57 58 To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'`` 59 to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you 60 should 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 67 For 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 79 following 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 102 Notes: 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 159 Once ``LocaleMiddleware`` determines the user's preference, it makes this 160 preference available as ``request.LANGUAGE_CODE`` for each 161 :class:`~django.http.HttpRequest`. Feel free to read this value in your view 162 code. 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 170 Note that, with static (middleware-less) translation, the language is in 171 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's 172 in ``request.LANGUAGE_CODE``. 173 174 .. _settings file: ../settings/ 175 .. _middleware documentation: ../middleware/ 176 .. _session: ../sessions/ 177 .. _request object: ../request_response/#httprequest-objects 178 179 How Django discovers translations 180 --------------------------------- 181 182 As described in :ref:`using-translations-in-your-own-projects`, 183 at 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 193 In all cases the name of the directory containing the translation is expected to 194 be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``, 195 etc. -
new file docs/topics/i18n/index.txt
diff -r 10ee88612fd8 docs/topics/i18n/index.txt
- + 1 .. _topics-i18n: 2 3 ===================================== 4 Internationalization and localization 5 ===================================== 6 7 Overview 8 ======== 9 10 Django has full support for internationalization of text in code and 11 templates, and format localization of dates and numbers. Here's how it works. 12 13 Essentially, 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 20 The complete process can be seen as divided in three stages. It is also possible 21 to identify an identical number of roles with very well defined responsabilities 22 associated with each of these tasks (although it's perfectly normal if you 23 find 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 40 For more general information about the topic, see the `GNU gettext documentation`_ 41 and the `Wikipedia article`_ 42 43 .. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts 44 .. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization 45 46 Glossary 47 ======== 48 49 First 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 76 Specialties of Django translation 77 ================================== 78 79 Django's translation machinery uses the standard ``gettext`` module that comes 80 with Python. If you know ``gettext``, you might note these specialties in the 81 way 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 95 Django 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 101 Django uses technical message IDs to translate date formats and time formats. 102 Technical message IDs are :term:`translation string`\s and can be easily 103 recognized; they're all upper case. You don't translate the message ID as with 104 other translation strings, you provide the correct local variant on the provided 105 English value. The format is identical to the format strings used by the 106 ``now`` template tag. 107 108 For example, with ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), 109 this would be the format string that you want to use in your language. A Django 110 contributor 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 ==================== 4 Internationalization 5 ==================== 6 7 Overview 8 ======== 9 10 The goal of internationalization is to allow a single Web application to offer 11 its content and functionality in multiple languages and locales. 12 13 For text translations, you, the Django developer, can accomplish this goal by 14 adding a minimal amount of hooks to your Python and templates. These hooks 15 are called **translation strings**. They tell Django: "This text should be 16 translated into the end user's language, if a translation for this text is 17 available in that language." It's your responsibility to mark translatable 18 strings; the system can only translate strings it knows about. 19 20 Django takes care of using these hooks to translate Web apps, on the fly, 21 according to users' language preferences. 22 23 Specifying translation strings: In Python code 24 ============================================== 25 26 Standard translation 27 -------------------- 28 29 Specify a translation string by using the function ``ugettext()``. It's 30 convention 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 50 In this example, the text ``"Welcome to my site."`` is marked as a translation 51 string:: 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 59 Obviously, you could code this without using the alias. This example is 60 identical 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 68 Translation works on computed values. This example is identical to the previous 69 two:: 70 71 def my_view(request): 72 words = ['Welcome', 'to', 'my', 'site.'] 73 output = _(' '.join(words)) 74 return HttpResponse(output) 75 76 Translation 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 84 examples, 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 88 The strings you pass to ``_()`` or ``ugettext()`` can take placeholders, 89 specified 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 95 This technique lets language-specific translations reorder the placeholder 96 text. For example, an English translation may be ``"Today is November, 26."``, 97 while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the 98 placeholders (the month and the day) with their positions swapped. 99 100 For this reason, you should use named-string interpolation (e.g., ``%(day)s``) 101 instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you 102 have more than a single parameter. If you used positional interpolation, 103 translations wouldn't be able to reorder placeholder text. 104 105 Marking strings as no-op 106 ------------------------ 107 108 Use the function ``django.utils.translation.ugettext_noop()`` to mark a string 109 as a translation string without translating it. The string is later translated 110 from a variable. 111 112 Use this if you have constant strings that should be stored in the source 113 language because they are exchanged over systems or users -- such as strings in 114 a database -- but should be translated at the last possible point in time, such 115 as when the string is presented to the user. 116 117 Pluralization 118 ------------- 119 120 Use the function ``django.utils.translation.ungettext()`` to specify pluralized 121 messages. 122 123 ``ungettext`` takes three arguments: the singular translation string, the plural 124 translation string and the number of objects. 125 126 This function is useful when you need your Django application to be localizable 127 to languages where the number and complexity of `plural forms 128 <http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is 129 greater 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 131 of its value.) 132 133 For 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 142 In this example the number of objects is passed to the translation languages as 143 the ``count`` variable. 144 145 Lets 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 164 Here we reuse localizable, hopefully already translated literals (contained in 165 the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for 166 other parts of the sentence so all of it is consistently based on the 167 cardinality 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 200 Lazy translation 201 ---------------- 202 203 Use the function ``django.utils.translation.ugettext_lazy()`` to translate 204 strings lazily -- when the value is accessed rather than when the 205 ``ugettext_lazy()`` function is called. 206 207 For 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 214 In this example, ``ugettext_lazy()`` stores a lazy reference to the string -- 215 not the actual translation. The translation itself will be done when the string 216 is used in a string context, such as template rendering on the Django admin 217 site. 218 219 The result of a ``ugettext_lazy()`` call can be used wherever you would use a 220 unicode string (an object with type ``unicode``) in Python. If you try to use 221 it where a bytestring (a ``str`` object) is expected, things will not work as 222 expected, since a ``ugettext_lazy()`` object doesn't know how to convert 223 itself to a bytestring. You can't use a unicode string inside a bytestring, 224 either, 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 233 If 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 237 If 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 245 Always use lazy translations in :ref:`Django models <topics-db-models>`. 246 Field names and table names should be marked for translation (otherwise, they 247 won't be translated in the admin interface). This means writing explicit 248 ``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class, 249 though, rather than relying on Django's default determination of 250 ``verbose_name`` and ``verbose_name_plural`` by looking at the model's class 251 name:: 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 261 Working with lazy translation objects 262 ------------------------------------- 263 264 .. highlightlang:: python 265 266 Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models 267 and utility functions is a common operation. When you're working with these 268 objects elsewhere in your code, you should ensure that you don't accidentally 269 convert 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 271 couple of helper functions. 272 273 Joining strings: string_concat() 274 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 275 276 Standard Python string joins (``''.join([...])``) will not work on lists 277 containing lazy translation objects. Instead, you can use 278 ``django.utils.translation.string_concat()``, which creates a lazy object that 279 concatenates its contents *and* converts them to strings only when the result 280 is 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 288 In this case, the lazy translations in ``result`` will only be converted to 289 strings when ``result`` itself is used in a string (usually at template 290 rendering time). 291 292 The allow_lazy() decorator 293 ~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 295 Django offers many utility functions (particularly in ``django.utils``) that 296 take a string as their first argument and do something to that string. These 297 functions are used by template filters as well as directly in other code. 298 299 If you write your own similar functions and deal with translations, you'll 300 face the problem of what to do when the first argument is a lazy translation 301 object. You don't want to convert it to a string immediately, because you might 302 be using this function outside of a view (and hence the current thread's locale 303 setting will not be correct). 304 305 For cases like this, use the ``django.utils.functional.allow_lazy()`` 306 decorator. It modifies the function so that *if* it's called with a lazy 307 translation as the first argument, the function evaluation is delayed until it 308 needs to be converted to a string. 309 310 For 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 319 The ``allow_lazy()`` decorator takes, in addition to the function to decorate, 320 a number of extra arguments (``*args``) specifying the type(s) that the 321 original function can return. Usually, it's enough to include ``unicode`` here 322 and ensure that your function returns only Unicode strings. 323 324 Using this decorator means you can write your function and assume that the 325 input is a proper string, then add support for lazy translation objects at the 326 end. 327 328 Specifying translation strings: In template code 329 ================================================ 330 331 .. highlightlang:: html+django 332 333 Translations in :ref:`Django templates <topics-templates>` uses two template 334 tags and a slightly different syntax than in Python code. To give your template 335 access to these tags, put ``{% load i18n %}`` toward the top of your template. 336 337 The ``{% 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 343 If the ``noop`` option is present, variable lookup still takes place but the 344 translation is skipped. This is useful when "stubbing out" content that will 345 require translation in the future:: 346 347 <title>{% trans "myvar" noop %}</title> 348 349 Internally, inline translations use an ``ugettext`` call. 350 351 It'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 357 To translate a template expression -- say, using template filters -- you need 358 to bind the expression to a local variable for use within the translation 359 block:: 360 361 {% blocktrans with value|filter as myvar %} 362 This will have {{ myvar }} inside. 363 {% endblocktrans %} 364 365 If you need to bind more than one expression inside a ``blocktrans`` tag, 366 separate 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 372 To 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 382 When you use the pluralization feature and bind additional values to local 383 variables apart from the counter value that selects the translated literal to be 384 used, have in mind that the ``blocktrans`` construct is internally converted 385 to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext 386 variables <pluralization-var-notes>` apply. 387 388 Each ``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 402 If you don't use the ``RequestContext`` extension, you can get those values with 403 three tags:: 404 405 {% get_current_language as LANGUAGE_CODE %} 406 {% get_available_languages as LANGUAGES %} 407 {% get_current_language_bidi as LANGUAGE_BIDI %} 408 409 These tags also require a ``{% load i18n %}``. 410 411 Translation hooks are also available within any template block tag that accepts 412 constant strings. In those cases, just use ``_()`` syntax to specify a 413 translation string:: 414 415 {% some_special_tag _("Page not found") value|yesno:_("yes,no") %} 416 417 In this case, both the tag and the filter will see the already-translated 418 string, 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 430 Specifying translation strings: In JavaScript code 431 ================================================== 432 433 Adding 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 443 Django provides an integrated solution for these problems: It passes the 444 translations into JavaScript, so you can call ``gettext``, etc., from within 445 JavaScript. 446 447 The ``javascript_catalog`` view 448 ------------------------------- 449 450 The main solution to these problems is the ``javascript_catalog`` view, which 451 sends out a JavaScript code library with functions that mimic the ``gettext`` 452 interface, plus an array of translation strings. Those translation strings are 453 taken from the application, project or Django core, according to what you 454 specify in either the info_dict or the URL. 455 456 You 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 466 Each string in ``packages`` should be in Python dotted-package syntax (the 467 same format as the strings in ``INSTALLED_APPS``) and should refer to a package 468 that contains a ``locale`` directory. If you specify multiple packages, all 469 those catalogs are merged into one catalog. This is useful if you have 470 JavaScript that uses strings from different applications. 471 472 You 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 478 With this, you specify the packages as a list of package names delimited by '+' 479 signs in the URL. This is especially useful if your pages use code from 480 different apps and this changes often and you don't want to pull in one big 481 catalog file. As a security measure, these values can only be either 482 ``django.conf`` or any package from the ``INSTALLED_APPS`` setting. 483 484 Using the JavaScript translation catalog 485 ---------------------------------------- 486 487 To 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 491 This uses reverse URL lookup to find the URL of the JavaScript catalog view. 492 When 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 497 There 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 503 and even a string interpolation function:: 504 505 function interpolate(fmt, obj, named); 506 507 The interpolation syntax is borrowed from Python, so the ``interpolate`` 508 function 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 533 You shouldn't go over the top with string interpolation, though: this is still 534 JavaScript, so the code has to make repeated regular-expression substitutions. 535 This isn't as fast as string interpolation in Python, so keep it to those 536 cases where you really need it (for example, in conjunction with ``ngettext`` 537 to produce proper pluralizations). 538 539 The ``set_language`` redirect view 540 ================================== 541 542 As a convenience, Django comes with a view, ``django.views.i18n.set_language``, 543 that sets a user's language preference and redirects back to the previous page. 544 545 Activate 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 551 The view expects to be called via the ``POST`` method, with a ``language`` 552 parameter set in request. If session support is enabled, the view 553 saves the language choice in the user's session. Otherwise, it saves the 554 language choice in a cookie that is by default named ``django_language``. 555 (The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.) 556 557 After setting the language choice, Django redirects the user, following this 558 algorithm: 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 566 Here'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 ============ 4 Localization 5 ============ 6 7 This document covers two localization-related topics: `Creating language 8 files`_ 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 19 How to create language files 20 ============================ 21 22 Once the string literals of an application have been tagged for later 23 translation, the translation themselves need to be written (or obtained). Here's 24 how 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 41 Message files 42 ------------- 43 44 The first step is to create a :term:`message file` for a new language. A message 45 file is a plain-text file, representing a single language, that contains all 46 available translation strings and how they should be represented in the given 47 language. Message files have a ``.po`` file extension. 48 49 Django comes with a tool, ``django-admin.py makemessages``, that automates the 50 creation 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 67 To 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. 72 The language code, in this case, is in :term:`locale format<locale name>`. For 73 example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian 74 German. 75 76 The 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 81 Th script runs over your project source tree or your application source tree and 82 pulls out all strings marked for translation. It creates (or updates) a message 83 file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the 84 file will be ``locale/de/LC_MESSAGES/django.po``. 85 86 By 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 92 Separate multiple extensions with commas and/or use ``-e`` or ``--extension`` 93 multiple times:: 94 95 django-admin.py makemessages -l de -e html,txt -e xml 96 97 When :ref:`creating message files from JavaScript source code 98 <creating-message-files-from-js-code>` you need to use the special 'djangojs' 99 domain, **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 115 The format of ``.po`` files is straightforward. Each ``.po`` file contains a 116 small bit of metadata, such as the translation maintainer's contact 117 information, but the bulk of the file is a list of **messages** -- simple 118 mappings between translation strings and the actual translated text for the 119 particular language. 120 121 For 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 127 containing the following snippet -- a message:: 128 129 #: path/to/python/module.py:23 130 msgid "Welcome to my site." 131 msgstr "" 132 133 A 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 144 Long 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 146 written over the next few lines as one string per line. Those strings are 147 directly concatenated. Don't forget trailing spaces within the strings; 148 otherwise, 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 160 To reexamine all source code and templates for new translation strings and 161 update all message files for **all** languages, run this:: 162 163 django-admin.py makemessages -a 164 165 Compiling message files 166 ----------------------- 167 168 After you create your message file -- and each time you make changes to it -- 169 you'll need to compile it into a more efficient form, for use by ``gettext``. 170 Do this with the ``django-admin.py compilemessages`` utility. 171 172 This tool runs over all available ``.po`` files and creates ``.mo`` files, which 173 are binary files optimized for use by ``gettext``. In the same directory from 174 which you ran ``django-admin.py makemessages``, run ``django-admin.py 175 compilemessages`` like this:: 176 177 django-admin.py compilemessages 178 179 That'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 195 Creating message files from JavaScript source code 196 ================================================== 197 198 You create and update the message files the same way as the other Django message 199 files -- with the ``django-admin.py makemessages`` tool. The only difference is 200 you need to provide a ``-d djangojs`` parameter, like this:: 201 202 django-admin.py makemessages -d djangojs -l de 203 204 This would create or update the message file for JavaScript for German. 205 After updating message files, just run ``django-admin.py compilemessages`` 206 the same way as you do with normal Django message files. 207 208 .. _gettext_on_windows: 209 210 ``gettext`` on Windows 211 ====================== 212 213 This is only needed for people who either want to extract message IDs or compile 214 message files (``.po``). Translation work itself just involves editing existing 215 files of this type, but if you want to create your own message files, or want to 216 test 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 239 You may also use ``gettext`` binaries you have obtained elsewhere, so long as 240 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries 241 have been found to not support this command. Do not attempt to use Django 242 translation 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 248 Format localization 249 =================== 250 251 Django's formatting system is disabled by default. To enable it, it's necessay 252 to set :setting:`USE_L10N = True <USE_L10N>` in your settings file. 253 254 When using Django's formatting system, dates and numbers on templates will be 255 displayed using the format specified for the current locale. Two users 256 accessing the same content, but in different language, will see date and 257 number fields formatted in different ways, depending on the format for their 258 current locale. 259 260 Django will also use localized formats when parsing data in forms. That means 261 Django uses different formats for different locales when guessing the format 262 used by the user when inputting data on forms. Note that Django uses different 263 formats for displaying data, and for parsing it. 264 265 Creating custom format files 266 ---------------------------- 267 268 Django provides format definitions for many locales, but sometimes you might 269 want to create your own, because a format files doesn't exist for your locale, 270 or because you want to overwrite some of the values. 271 272 To use custom formats, first thing to do, is to specify the path where you'll 273 place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH` 274 setting to the the path (in the format ``'foo.bar.baz``) where format files 275 will exists. 276 277 Files are not placed directly in this directory, but in a directory named as 278 the locale, and must be named ``formats.py``. 279 280 To 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 289 where :file:`formats.py` contains custom format definitions. For example:: 290 291 THOUSAND_SEPARATOR = ' ' 292 293 to use a space as a thousand separator, instead of the default for English, 294 a comma. -
docs/topics/index.txt
diff -r 10ee88612fd8 docs/topics/index.txt
a b 21 21 cache 22 22 conditional-view-processing 23 23 email 24 i18n 24 i18n/index 25 25 pagination 26 26 serialization 27 27 settings