Ticket #10260: 10260-i18n-docs-rf-r12229.diff
File 10260-i18n-docs-rf-r12229.diff, 104.7 KB (added by , 15 years ago) |
---|
-
django/conf/global_settings.py
diff -r 257fac48943d django/conf/global_settings.py
a b 298 298 # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now 299 299 MONTH_DAY_FORMAT = 'F j' 300 300 301 # Default short formatting for date objects. See all available format strings here:301 # Default short formatting for date objects. See all available format strings here: 302 302 # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now 303 303 SHORT_DATE_FORMAT = 'm/d/Y' 304 304 -
new file docs/howto/i18n.txt
diff -r 257fac48943d 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 257fac48943d 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 257fac48943d 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 257fac48943d docs/ref/settings.txt
a b 852 852 Default: ``'en-us'`` 853 853 854 854 A string representing the language code for this installation. This should be in 855 standard language format. For example, U.S. English is ``"en-us"``. See856 :ref:`topics-i18n`.855 standard :term:`language format<language code>`. For example, U.S. English is 856 ``"en-us"``. See :ref:`topics-i18n`. 857 857 858 858 .. setting:: LANGUAGE_COOKIE_NAME 859 859 … … 880 880 881 881 .. _online source: http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py 882 882 883 The list is a tuple of two-tuples in the format (language code, language 884 name) -- for example, ``('ja', 'Japanese')``. This specifies which languages 885 are available for language selection. See :ref:`topics-i18n`. 883 The list is a tuple of two-tuples in the format ``(language code, language 884 name)``, the ``language code`` part should be a 885 :term:`language name<language code>` -- for example, ``('ja', 'Japanese')``. 886 This specifies which languages are available for language selection. See 887 :ref:`topics-i18n`. 886 888 887 889 Generally, the default value should suffice. Only set this setting if you want 888 890 to restrict language selection to a subset of the Django-provided languages. … … 917 919 Default: ``()`` (Empty tuple) 918 920 919 921 A tuple of directories where Django looks for translation files. 920 See :ref:` translations-in-your-own-projects`.922 See :ref:`using-translations-in-your-own-projects`. 921 923 922 924 .. setting:: LOGIN_REDIRECT_URL 923 925 -
docs/releases/1.2.txt
diff -r 257fac48943d docs/releases/1.2.txt
a b 367 367 django.form.fields to django.core.validators. You will need to update 368 368 your imports if you are using it. 369 369 370 Technical message IDs 371 --------------------- 372 373 Up to version 1.1 Django used :ref:`technical message IDs<technical-messages>` 374 to provide localizers the possibility to translate date and time formats. They 375 were translatable :term:`translation string`\s that could be recognized because 376 they were all upper case (for example ``DATETIME_FORMAT``, ``DATE_FORMAT``, 377 ``TIME_FORMAT``). They have been deprecated in favor of the new :ref:`Format 378 localization <format-localization>` infrastructure that allows localizers to 379 specify that information in a ``formats.py`` file in the corresponding 380 ``django/conf/locale/<locale name>/`` directory. 381 370 382 What's new in Django 1.2 371 383 ======================== 372 384 … … 431 443 ... 432 444 {% endifnotequal %} 433 445 434 You can now do this: :446 You can now do this: 435 447 436 448 .. code-block:: html+django 437 449 -
deleted file docs/topics/i18n.txt
diff -r 257fac48943d 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 To create or update a message file, run this command::516 517 django-admin.py makemessages -l de518 519 ...where ``de`` is the language code for the message file you want to create.520 The language code, in this case, is in locale format. For example, it's521 ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German.522 523 The script should be run from one of three places:524 525 * The root directory of your Django project.526 * The root directory of your Django app.527 * The root ``django`` directory (not a Subversion checkout, but the one528 that is linked-to via ``$PYTHONPATH`` or is located somewhere on that529 path). This is only relevant when you are creating a translation for530 Django itself, see :ref:`contributing-translations`.531 532 The script runs over your project source tree or your application source tree533 and pulls out all strings marked for translation. It creates (or updates) a534 message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``535 example, the file will be ``locale/de/LC_MESSAGES/django.po``.536 537 By default ``django-admin.py makemessages`` examines every file that has the538 ``.html`` file extension. In case you want to override that default, use the539 ``--extension`` or ``-e`` option to specify the file extensions to examine::540 541 django-admin.py makemessages -l de -e txt542 543 Separate multiple extensions with commas and/or use ``-e`` or ``--extension``544 multiple times::545 546 django-admin.py makemessages -l=de -e=html,txt -e xml547 548 When `creating JavaScript translation catalogs`_ you need to use the special549 'djangojs' domain, **not** ``-e js``.550 551 .. admonition:: No gettext?552 553 If you don't have the ``gettext`` utilities installed, ``django-admin.py554 makemessages`` will create empty files. If that's the case, either install555 the ``gettext`` utilities or just copy the English message file556 (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting557 point; it's just an empty translation file.558 559 .. admonition:: Working on Windows?560 561 If you're using Windows and need to install the GNU gettext utilities so562 ``django-admin makemessages`` works see `gettext on Windows`_ for more563 information.564 565 The format of ``.po`` files is straightforward. Each ``.po`` file contains a566 small bit of metadata, such as the translation maintainer's contact567 information, but the bulk of the file is a list of **messages** -- simple568 mappings between translation strings and the actual translated text for the569 particular language.570 571 For example, if your Django app contained a translation string for the text572 ``"Welcome to my site."``, like so::573 574 _("Welcome to my site.")575 576 ...then ``django-admin.py makemessages`` will have created a ``.po`` file577 containing the following snippet -- a message::578 579 #: path/to/python/module.py:23580 msgid "Welcome to my site."581 msgstr ""582 583 A quick explanation:584 585 * ``msgid`` is the translation string, which appears in the source. Don't586 change it.587 * ``msgstr`` is where you put the language-specific translation. It starts588 out empty, so it's your responsibility to change it. Make sure you keep589 the quotes around your translation.590 * As a convenience, each message includes, in the form of a comment line591 prefixed with ``#`` and located above the ``msgid`` line, the filename592 and line number from which the translation string was gleaned.593 594 Long messages are a special case. There, the first string directly after the595 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be596 written over the next few lines as one string per line. Those strings are597 directly concatenated. Don't forget trailing spaces within the strings;598 otherwise, they'll be tacked together without whitespace!599 600 .. admonition:: Mind your charset601 602 When creating a PO file with your favorite text editor, first edit603 the charset line (search for ``"CHARSET"``) and set it to the charset604 you'll be using to edit the content. Due to the way the ``gettext`` tools605 work internally and because we want to allow non-ASCII source strings in606 Django's core and your applications, you **must** use UTF-8 as the encoding607 for your PO file. This means that everybody will be using the same608 encoding, which is important when Django processes the PO files.609 610 To reexamine all source code and templates for new translation strings and611 update all message files for **all** languages, run this::612 613 django-admin.py makemessages -a614 615 Compiling message files616 -----------------------617 618 After you create your message file -- and each time you make changes to it --619 you'll need to compile it into a more efficient form, for use by ``gettext``.620 Do this with the ``django-admin.py compilemessages`` utility.621 622 This tool runs over all available ``.po`` files and creates ``.mo`` files,623 which are binary files optimized for use by ``gettext``. In the same directory624 from which you ran ``django-admin.py makemessages``, run ``django-admin.py625 compilemessages`` like this::626 627 django-admin.py compilemessages628 629 That's it. Your translations are ready for use.630 631 .. admonition:: A note to Django veterans632 633 The old tool ``bin/compile-messages.py`` has been moved to the command634 ``django-admin.py compilemessages`` to provide consistency throughout635 Django.636 637 .. admonition:: Working on Windows?638 639 If you're using Windows and need to install the GNU gettext utilities so640 ``django-admin compilemessages`` works see `gettext on Windows`_ for more641 information.642 643 .. _how-django-discovers-language-preference:644 645 3. How Django discovers language preference646 ===========================================647 648 Once you've prepared your translations -- or, if you just want to use the649 translations that come with Django -- you'll just need to activate translation650 for your app.651 652 Behind the scenes, Django has a very flexible model of deciding which language653 should be used -- installation-wide, for a particular user, or both.654 655 To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.656 Django uses this language as the default translation -- the final attempt if no657 other translator finds a translation.658 659 If all you want to do is run Django with your native language, and a language660 file is available for your language, all you need to do is set661 ``LANGUAGE_CODE``.662 663 If you want to let each individual user specify which language he or she664 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language665 selection based on data from the request. It customizes content for each user.666 667 To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``668 to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you669 should follow these guidelines:670 671 * Make sure it's one of the first middlewares installed.672 * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``673 makes use of session data.674 * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.675 676 For example, your ``MIDDLEWARE_CLASSES`` might look like this::677 678 MIDDLEWARE_CLASSES = (679 'django.contrib.sessions.middleware.SessionMiddleware',680 'django.middleware.locale.LocaleMiddleware',681 'django.middleware.common.CommonMiddleware',682 )683 684 (For more on middleware, see the :ref:`middleware documentation685 <topics-http-middleware>`.)686 687 ``LocaleMiddleware`` tries to determine the user's language preference by688 following this algorithm:689 690 * First, it looks for a ``django_language`` key in the current user's691 session.692 693 * Failing that, it looks for a cookie.694 695 .. versionchanged:: 1.0696 697 In Django version 0.96 and before, the cookie's name is hard-coded to698 ``django_language``. In Django 1,0, The cookie name is set by the699 ``LANGUAGE_COOKIE_NAME`` setting. (The default name is700 ``django_language``.)701 702 * Failing that, it looks at the ``Accept-Language`` HTTP header. This703 header is sent by your browser and tells the server which language(s) you704 prefer, in order by priority. Django tries each language in the header705 until it finds one with available translations.706 707 * Failing that, it uses the global ``LANGUAGE_CODE`` setting.708 709 .. _locale-middleware-notes:710 711 Notes:712 713 * In each of these places, the language preference is expected to be in the714 standard language format, as a string. For example, Brazilian Portuguese715 is ``pt-br``.716 717 * If a base language is available but the sublanguage specified is not,718 Django uses the base language. For example, if a user specifies ``de-at``719 (Austrian German) but Django only has ``de`` available, Django uses720 ``de``.721 722 * Only languages listed in the :setting:`LANGUAGES` setting can be selected.723 If you want to restrict the language selection to a subset of provided724 languages (because your application doesn't provide all those languages),725 set ``LANGUAGES`` to a list of languages. For example::726 727 LANGUAGES = (728 ('de', _('German')),729 ('en', _('English')),730 )731 732 This example restricts languages that are available for automatic733 selection to German and English (and any sublanguage, like de-ch or734 en-us).735 736 .. _LANGUAGES setting: ../settings/#languages737 738 * If you define a custom ``LANGUAGES`` setting, as explained in the739 previous bullet, it's OK to mark the languages as translation strings740 -- but use a "dummy" ``ugettext()`` function, not the one in741 ``django.utils.translation``. You should *never* import742 ``django.utils.translation`` from within your settings file, because that743 module in itself depends on the settings, and that would cause a circular744 import.745 746 The solution is to use a "dummy" ``ugettext()`` function. Here's a sample747 settings file::748 749 ugettext = lambda s: s750 751 LANGUAGES = (752 ('de', ugettext('German')),753 ('en', ugettext('English')),754 )755 756 With this arrangement, ``django-admin.py makemessages`` will still find757 and mark these strings for translation, but the translation won't happen758 at runtime -- so you'll have to remember to wrap the languages in the759 *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.760 761 * The ``LocaleMiddleware`` can only select languages for which there is a762 Django-provided base translation. If you want to provide translations763 for your application that aren't already in the set of translations764 in Django's source tree, you'll want to provide at least basic765 translations for that language. For example, Django uses technical766 message IDs to translate date formats and time formats -- so you will767 need at least those translations for the system to work correctly.768 769 A good starting point is to copy the English ``.po`` file and to770 translate at least the technical messages -- maybe the validation771 messages, too.772 773 Technical message IDs are easily recognized; they're all upper case. You774 don't translate the message ID as with other messages, you provide the775 correct local variant on the provided English value. For example, with776 ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would777 be the format string that you want to use in your language. The format778 is identical to the format strings used by the ``now`` template tag.779 780 Once ``LocaleMiddleware`` determines the user's preference, it makes this781 preference available as ``request.LANGUAGE_CODE`` for each782 :class:`~django.http.HttpRequest`. Feel free to read this value in your view783 code. Here's a simple example::784 785 def hello_world(request, count):786 if request.LANGUAGE_CODE == 'de-at':787 return HttpResponse("You prefer to read Austrian German.")788 else:789 return HttpResponse("You prefer to read another language.")790 791 Note that, with static (middleware-less) translation, the language is in792 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's793 in ``request.LANGUAGE_CODE``.794 795 .. _settings file: ../settings/796 .. _middleware documentation: ../middleware/797 .. _session: ../sessions/798 .. _request object: ../request_response/#httprequest-objects799 800 .. _translations-in-your-own-projects:801 802 Using translations in your own projects803 =======================================804 805 Django looks for translations by following this algorithm:806 807 * First, it looks for a ``locale`` directory in the application directory808 of the view that's being called. If it finds a translation for the809 selected language, the translation will be installed.810 * Next, it looks for a ``locale`` directory in the project directory. If it811 finds a translation, the translation will be installed.812 * Finally, it checks the Django-provided base translation in813 ``django/conf/locale``.814 815 This way, you can write applications that include their own translations, and816 you can override base translations in your project path. Or, you can just build817 a big project out of several apps and put all translations into one big project818 message file. The choice is yours.819 820 .. note::821 822 If you're using manually configured settings, as described823 :ref:`settings-without-django-settings-module`, the ``locale`` directory in824 the project directory will not be examined, since Django loses the ability825 to work out the location of the project directory. (Django normally uses826 the location of the settings file to determine this, and a settings file827 doesn't exist if you're manually configuring your settings.)828 829 All message file repositories are structured the same way. They are:830 831 * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``832 * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``833 * All paths listed in ``LOCALE_PATHS`` in your settings file are834 searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``835 * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``836 837 To create message files, you use the same ``django-admin.py makemessages``838 tool as with the Django message files. You only need to be in the right place839 -- in the directory where either the ``conf/locale`` (in case of the source840 tree) or the ``locale/`` (in case of app messages or project messages)841 directory are located. And you use the same ``django-admin.py842 compilemessages`` to produce the binary ``django.mo`` files that are used by843 ``gettext``.844 845 You can also run ``django-admin.py compilemessages846 --settings=path.to.settings`` to make the compiler process all the directories847 in your ``LOCALE_PATHS`` setting.848 849 Application message files are a bit complicated to discover -- they need the850 ``LocaleMiddleware``. If you don't use the middleware, only the Django message851 files and project message files will be processed.852 853 Finally, you should give some thought to the structure of your translation854 files. If your applications need to be delivered to other users and will855 be used in other projects, you might want to use app-specific translations.856 But using app-specific translations and project translations could produce857 weird problems with ``makemessages``: ``makemessages`` will traverse all858 directories below the current path and so might put message IDs into the859 project message file that are already in application message files.860 861 The easiest way out is to store applications that are not part of the project862 (and so carry their own translations) outside the project tree. That way,863 ``django-admin.py makemessages`` on the project level will only translate864 strings that are connected to your explicit project and not strings that are865 distributed independently.866 867 The ``set_language`` redirect view868 ==================================869 870 As a convenience, Django comes with a view, ``django.views.i18n.set_language``,871 that sets a user's language preference and redirects back to the previous page.872 873 Activate this view by adding the following line to your URLconf::874 875 (r'^i18n/', include('django.conf.urls.i18n')),876 877 (Note that this example makes the view available at ``/i18n/setlang/``.)878 879 The view expects to be called via the ``POST`` method, with a ``language``880 parameter set in request. If session support is enabled, the view881 saves the language choice in the user's session. Otherwise, it saves the882 language choice in a cookie that is by default named ``django_language``.883 (The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)884 885 After setting the language choice, Django redirects the user, following this886 algorithm:887 888 * Django looks for a ``next`` parameter in the ``POST`` data.889 * If that doesn't exist, or is empty, Django tries the URL in the890 ``Referrer`` header.891 * If that's empty -- say, if a user's browser suppresses that header --892 then the user will be redirected to ``/`` (the site root) as a fallback.893 894 Here's example HTML template code:895 896 .. code-block:: html+django897 898 <form action="/i18n/setlang/" method="post">899 <input name="next" type="hidden" value="/next/page/" />900 <select name="language">901 {% for lang in LANGUAGES %}902 <option value="{{ lang.0 }}">{{ lang.1 }}</option>903 {% endfor %}904 </select>905 <input type="submit" value="Go" />906 </form>907 908 Translations and JavaScript909 ===========================910 911 Adding translations to JavaScript poses some problems:912 913 * JavaScript code doesn't have access to a ``gettext`` implementation.914 915 * JavaScript code doesn't have access to .po or .mo files; they need to be916 delivered by the server.917 918 * The translation catalogs for JavaScript should be kept as small as919 possible.920 921 Django provides an integrated solution for these problems: It passes the922 translations into JavaScript, so you can call ``gettext``, etc., from within923 JavaScript.924 925 The ``javascript_catalog`` view926 -------------------------------927 928 The main solution to these problems is the ``javascript_catalog`` view, which929 sends out a JavaScript code library with functions that mimic the ``gettext``930 interface, plus an array of translation strings. Those translation strings are931 taken from the application, project or Django core, according to what you932 specify in either the info_dict or the URL.933 934 You hook it up like this::935 936 js_info_dict = {937 'packages': ('your.app.package',),938 }939 940 urlpatterns = patterns('',941 (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),942 )943 944 Each string in ``packages`` should be in Python dotted-package syntax (the945 same format as the strings in ``INSTALLED_APPS``) and should refer to a package946 that contains a ``locale`` directory. If you specify multiple packages, all947 those catalogs are merged into one catalog. This is useful if you have948 JavaScript that uses strings from different applications.949 950 You can make the view dynamic by putting the packages into the URL pattern::951 952 urlpatterns = patterns('',953 (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),954 )955 956 With this, you specify the packages as a list of package names delimited by '+'957 signs in the URL. This is especially useful if your pages use code from958 different apps and this changes often and you don't want to pull in one big959 catalog file. As a security measure, these values can only be either960 ``django.conf`` or any package from the ``INSTALLED_APPS`` setting.961 962 Using the JavaScript translation catalog963 ----------------------------------------964 965 To use the catalog, just pull in the dynamically generated script like this::966 967 <script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>968 969 This uses reverse URL lookup to find the URL of the JavaScript catalog view.970 When the catalog is loaded, your JavaScript code can use the standard971 ``gettext`` interface to access it::972 973 document.write(gettext('this is to be translated'));974 975 There is also an ``ngettext`` interface::976 977 var object_cnt = 1 // or 0, or 2, or 3, ...978 s = ngettext('literal for the singular case',979 'literal for the plural case', object_cnt);980 981 and even a string interpolation function::982 983 function interpolate(fmt, obj, named);984 985 The interpolation syntax is borrowed from Python, so the ``interpolate``986 function supports both positional and named interpolation:987 988 * Positional interpolation: ``obj`` contains a JavaScript Array object989 whose elements values are then sequentially interpolated in their990 corresponding ``fmt`` placeholders in the same order they appear.991 For example::992 993 fmts = ngettext('There is %s object. Remaining: %s',994 'There are %s objects. Remaining: %s', 11);995 s = interpolate(fmts, [11, 20]);996 // s is 'There are 11 objects. Remaining: 20'997 998 * Named interpolation: This mode is selected by passing the optional999 boolean ``named`` parameter as true. ``obj`` contains a JavaScript1000 object or associative array. For example::1001 1002 d = {1003 count: 101004 total: 501005 };1006 1007 fmts = ngettext('Total: %(total)s, there is %(count)s object',1008 'there are %(count)s of a total of %(total)s objects', d.count);1009 s = interpolate(fmts, d, true);1010 1011 You shouldn't go over the top with string interpolation, though: this is still1012 JavaScript, so the code has to make repeated regular-expression substitutions.1013 This isn't as fast as string interpolation in Python, so keep it to those1014 cases where you really need it (for example, in conjunction with ``ngettext``1015 to produce proper pluralizations).1016 1017 Creating JavaScript translation catalogs1018 ----------------------------------------1019 1020 You create and update the translation catalogs the same way as the other1021 1022 Django translation catalogs -- with the ``django-admin.py makemessages`` tool.1023 The only difference is you need to provide a ``-d djangojs`` parameter, like1024 this::1025 1026 django-admin.py makemessages -d djangojs -l de1027 1028 This would create or update the translation catalog for JavaScript for German.1029 After updating translation catalogs, just run ``django-admin.py1030 compilemessages`` the same way as you do with normal Django translation1031 catalogs.1032 1033 Specialties of Django translation1034 ==================================1035 1036 If you know ``gettext``, you might note these specialties in the way Django1037 does translation:1038 1039 * The string domain is ``django`` or ``djangojs``. This string domain is1040 used to differentiate between different programs that store their data1041 in a common message-file library (usually ``/usr/share/locale/``). The1042 ``django`` domain is used for python and template translation strings1043 and is loaded into the global translation catalogs. The ``djangojs``1044 domain is only used for JavaScript translation catalogs to make sure1045 that those are as small as possible.1046 * Django doesn't use ``xgettext`` alone. It uses Python wrappers around1047 ``xgettext`` and ``msgfmt``. This is mostly for convenience.1048 1049 ``gettext`` on Windows1050 ======================1051 1052 This is only needed for people who either want to extract message IDs or1053 compile message files (``.po``). Translation work itself just involves editing1054 existing files of this type, but if you want to create your own message files,1055 or want to test or compile a changed message file, you will need the1056 ``gettext`` utilities:1057 1058 * Download the following zip files from the GNOME servers1059 http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one1060 of its mirrors_1061 1062 * ``gettext-runtime-X.zip``1063 * ``gettext-tools-X.zip``1064 1065 ``X`` is the version number, we recomend using ``0.15`` or higher.1066 1067 * Extract the contents of the ``bin\`` directories in both files to the1068 same folder on your system (i.e. ``C:\Program Files\gettext-utils``)1069 1070 * Update the system PATH:1071 1072 * ``Control Panel > System > Advanced > Environment Variables``1073 * In the ``System variables`` list, click ``Path``, click ``Edit``1074 * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the1075 ``Variable value`` field1076 1077 .. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS1078 1079 You may also use ``gettext`` binaries you have obtained elsewhere, so long as1080 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries1081 have been found to not support this command. Do not attempt to use Django1082 translation utilities with a ``gettext`` package if the command ``xgettext1083 --version`` entered at a Windows command prompt causes a popup window saying1084 "xgettext.exe has generated errors and will be closed by Windows".1085 1086 .. _format-localization:1087 1088 Format localization1089 ===================1090 1091 Django's formatting system is disabled by default. To enable it, it's necessay1092 to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.1093 1094 When using Django's formatting system, dates and numbers on templates will be1095 displayed using the format specified for the current locale. Two users1096 accessing the same content, but in different language, will see date and1097 number fields formatted in different ways, depending on the format for their1098 current locale.1099 1100 Django will also use localized formats when parsing data in forms. That means1101 Django uses different formats for different locales when guessing the format1102 used by the user when inputting data on forms. Note that Django uses different1103 formats for displaying data, and for parsing it.1104 1105 Creating custom format files1106 ----------------------------1107 1108 Django provides format definitions for many locales, but sometimes you might1109 want to create your own, because a format files doesn't exist for your locale,1110 or because you want to overwrite some of the values.1111 1112 To use custom formats, first thing to do, is to specify the path where you'll1113 place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH`1114 setting to the the path (in the format ``'foo.bar.baz``) where format files1115 will exists.1116 1117 Files are not placed directly in this directory, but in a directory named as1118 the locale, and must be named ``formats.py``.1119 1120 To customize the English formats, a structure like this would be needed::1121 1122 mysite/1123 formats/1124 __init__.py1125 en/1126 __init__.py1127 formats.py1128 1129 where :file:`formats.py` contains custom format definitions. For example::1130 1131 THOUSAND_SEPARATOR = ' '1132 1133 to use a space as a thousand separator, instead of the default for English,1134 a comma. -
new file docs/topics/i18n/deployment.txt
diff -r 257fac48943d 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 257fac48943d 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 257fac48943d 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 257fac48943d 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 To create or update a message file, run this command:: 58 59 django-admin.py makemessages -l de 60 61 ...where ``de`` is the language code for the message file you want to create. 62 The language code, in this case, is in :term:`locale format<locale name>`. For 63 example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian 64 German. 65 66 The script should be run from one of two places: 67 68 * The root directory of your Django project. 69 * The root directory of your Django app. 70 71 Th script runs over your project source tree or your application source tree and 72 pulls out all strings marked for translation. It creates (or updates) a message 73 file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the 74 file will be ``locale/de/LC_MESSAGES/django.po``. 75 76 By default ``django-admin.py makemessages`` examines every file that has the 77 ``.html`` file extension. In case you want to override that default, use the 78 ``--extension`` or ``-e`` option to specify the file extensions to examine:: 79 80 django-admin.py makemessages -l de -e txt 81 82 Separate multiple extensions with commas and/or use ``-e`` or ``--extension`` 83 multiple times:: 84 85 django-admin.py makemessages -l=de -e=html,txt -e xml 86 87 When :ref:`creating message files from JavaScript source code 88 <creating-message-files-from-js-code>` you need to use the special 'djangojs' 89 domain, **not** ``-e js``. 90 91 .. admonition:: No gettext? 92 93 If you don't have the ``gettext`` utilities installed, ``django-admin.py 94 makemessages`` will create empty files. If that's the case, either install 95 the ``gettext`` utilities or just copy the English message file 96 (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting 97 point; it's just an empty translation file. 98 99 .. admonition:: Working on Windows? 100 101 If you're using Windows and need to install the GNU gettext utilities so 102 ``django-admin makemessages`` works see :ref:`gettext_on_windows` for more 103 information. 104 105 The format of ``.po`` files is straightforward. Each ``.po`` file contains a 106 small bit of metadata, such as the translation maintainer's contact 107 information, but the bulk of the file is a list of **messages** -- simple 108 mappings between translation strings and the actual translated text for the 109 particular language. 110 111 For example, if your Django app contained a translation string for the text 112 ``"Welcome to my site."``, like so:: 113 114 _("Welcome to my site.") 115 116 ...then ``django-admin.py makemessages`` will have created a ``.po`` file 117 containing the following snippet -- a message:: 118 119 #: path/to/python/module.py:23 120 msgid "Welcome to my site." 121 msgstr "" 122 123 A quick explanation: 124 125 * ``msgid`` is the translation string, which appears in the source. Don't 126 change it. 127 * ``msgstr`` is where you put the language-specific translation. It starts 128 out empty, so it's your responsibility to change it. Make sure you keep 129 the quotes around your translation. 130 * As a convenience, each message includes, in the form of a comment line 131 prefixed with ``#`` and located above the ``msgid`` line, the filename and 132 line number from which the translation string was gleaned. 133 134 Long messages are a special case. There, the first string directly after the 135 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be 136 written over the next few lines as one string per line. Those strings are 137 directly concatenated. Don't forget trailing spaces within the strings; 138 otherwise, they'll be tacked together without whitespace! 139 140 .. admonition:: Mind your charset 141 142 When creating a PO file with your favorite text editor, first edit 143 the charset line (search for ``"CHARSET"``) and set it to the charset 144 you'll be using to edit the content. Due to the way the ``gettext`` tools 145 work internally and because we want to allow non-ASCII source strings in 146 Django's core and your applications, you **must** use UTF-8 as the encoding 147 for your PO file. This means that everybody will be using the same 148 encoding, which is important when Django processes the PO files. 149 150 To reexamine all source code and templates for new translation strings and 151 update all message files for **all** languages, run this:: 152 153 django-admin.py makemessages -a 154 155 Compiling message files 156 ----------------------- 157 158 After you create your message file -- and each time you make changes to it -- 159 you'll need to compile it into a more efficient form, for use by ``gettext``. 160 Do this with the ``django-admin.py compilemessages`` utility. 161 162 This tool runs over all available ``.po`` files and creates ``.mo`` files, which 163 are binary files optimized for use by ``gettext``. In the same directory from 164 which you ran ``django-admin.py makemessages``, run ``django-admin.py 165 compilemessages`` like this:: 166 167 django-admin.py compilemessages 168 169 That's it. Your translations are ready for use. 170 171 .. admonition:: A note to Django veterans 172 173 The old tool ``bin/compile-messages.py`` has been moved to the command 174 ``django-admin.py compilemessages`` to provide consistency throughout 175 Django. 176 177 .. admonition:: Working on Windows? 178 179 If you're using Windows and need to install the GNU gettext utilities so 180 ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more 181 information. 182 183 .. _creating-message-files-from-js-code: 184 185 Creating message files from JavaScript source code 186 ================================================== 187 188 You create and update the message files the same way as the other Django message 189 files -- with the ``django-admin.py makemessages`` tool. The only difference is 190 you need to provide a ``-d djangojs`` parameter, like this:: 191 192 django-admin.py makemessages -d djangojs -l de 193 194 This would create or update the message file for JavaScript for German. 195 After updating message files, just run ``django-admin.py compilemessages`` 196 the same way as you do with normal Django message files. 197 198 .. _gettext_on_windows: 199 200 ``gettext`` on Windows 201 ====================== 202 203 This is only needed for people who either want to extract message IDs or compile 204 message files (``.po``). Translation work itself just involves editing existing 205 files of this type, but if you want to create your own message files, or want to 206 test or compile a changed message file, you will need the ``gettext`` utilities: 207 208 * Download the following zip files from the GNOME servers 209 http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one 210 of its mirrors_ 211 212 * ``gettext-runtime-X.zip`` 213 * ``gettext-tools-X.zip`` 214 215 ``X`` is the version number, we recomend using ``0.15`` or higher. 216 217 * Extract the contents of the ``bin\`` directories in both files to the 218 same folder on your system (i.e. ``C:\Program Files\gettext-utils``) 219 220 * Update the system PATH: 221 222 * ``Control Panel > System > Advanced > Environment Variables``. 223 * In the ``System variables`` list, click ``Path``, click ``Edit``. 224 * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the 225 ``Variable value`` field. 226 227 .. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS 228 229 You may also use ``gettext`` binaries you have obtained elsewhere, so long as 230 the ``xgettext --version`` command works properly. Some version 0.14.4 binaries 231 have been found to not support this command. Do not attempt to use Django 232 translation utilities with a ``gettext`` package if the command ``xgettext 233 --version`` entered at a Windows command prompt causes a popup window saying 234 "xgettext.exe has generated errors and will be closed by Windows". 235 236 .. _format-localization: 237 238 Format localization 239 =================== 240 241 Django's formatting system is disabled by default. To enable it, it's necessay 242 to set :setting:`USE_L10N = True <USE_L10N>` in your settings file. 243 244 When using Django's formatting system, dates and numbers on templates will be 245 displayed using the format specified for the current locale. Two users 246 accessing the same content, but in different language, will see date and 247 number fields formatted in different ways, depending on the format for their 248 current locale. 249 250 Django will also use localized formats when parsing data in forms. That means 251 Django uses different formats for different locales when guessing the format 252 used by the user when inputting data on forms. Note that Django uses different 253 formats for displaying data, and for parsing it. 254 255 Creating custom format files 256 ---------------------------- 257 258 Django provides format definitions for many locales, but sometimes you might 259 want to create your own, because a format files doesn't exist for your locale, 260 or because you want to overwrite some of the values. 261 262 To use custom formats, first thing to do, is to specify the path where you'll 263 place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH` 264 setting to the the path (in the format ``'foo.bar.baz``) where format files 265 will exists. 266 267 Files are not placed directly in this directory, but in a directory named as 268 the locale, and must be named ``formats.py``. 269 270 To customize the English formats, a structure like this would be needed:: 271 272 mysite/ 273 formats/ 274 __init__.py 275 en/ 276 __init__.py 277 formats.py 278 279 where :file:`formats.py` contains custom format definitions. For example:: 280 281 THOUSAND_SEPARATOR = ' ' 282 283 to use a space as a thousand separator, instead of the default for English, 284 a comma. -
docs/topics/index.txt
diff -r 257fac48943d 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