summaryrefslogtreecommitdiff
path: root/parts/django/docs/topics/i18n/internationalization.txt
diff options
context:
space:
mode:
Diffstat (limited to 'parts/django/docs/topics/i18n/internationalization.txt')
-rw-r--r--parts/django/docs/topics/i18n/internationalization.txt624
1 files changed, 0 insertions, 624 deletions
diff --git a/parts/django/docs/topics/i18n/internationalization.txt b/parts/django/docs/topics/i18n/internationalization.txt
deleted file mode 100644
index b6847ea..0000000
--- a/parts/django/docs/topics/i18n/internationalization.txt
+++ /dev/null
@@ -1,624 +0,0 @@
-====================
-Internationalization
-====================
-
-Overview
-========
-
-The goal of internationalization is to allow a single Web application to offer
-its content and functionality in multiple languages and locales.
-
-For text translations, you, the Django developer, can accomplish this goal by
-adding a minimal amount of hooks to your Python and templates. These hooks
-are called **translation strings**. They tell Django: "This text should be
-translated into the end user's language, if a translation for this text is
-available in that language." It's your responsibility to mark translatable
-strings; the system can only translate strings it knows about.
-
-Django takes care of using these hooks to translate Web apps, on the fly,
-according to users' language preferences.
-
-Specifying translation strings: In Python code
-==============================================
-
-Standard translation
---------------------
-
-Specify a translation string by using the function ``ugettext()``. It's
-convention to import this as a shorter alias, ``_``, to save typing.
-
-.. note::
- Python's standard library ``gettext`` module installs ``_()`` into the
- global namespace, as an alias for ``gettext()``. In Django, we have chosen
- not to follow this practice, for a couple of reasons:
-
- 1. For international character set (Unicode) support, ``ugettext()`` is
- more useful than ``gettext()``. Sometimes, you should be using
- ``ugettext_lazy()`` as the default translation method for a particular
- file. Without ``_()`` in the global namespace, the developer has to
- think about which is the most appropriate translation function.
-
- 2. The underscore character (``_``) is used to represent "the previous
- result" in Python's interactive shell and doctest tests. Installing a
- global ``_()`` function causes interference. Explicitly importing
- ``ugettext()`` as ``_()`` avoids this problem.
-
-.. highlightlang:: python
-
-In this example, the text ``"Welcome to my site."`` is marked as a translation
-string::
-
- from django.utils.translation import ugettext as _
-
- def my_view(request):
- output = _("Welcome to my site.")
- return HttpResponse(output)
-
-Obviously, you could code this without using the alias. This example is
-identical to the previous one::
-
- from django.utils.translation import ugettext
-
- def my_view(request):
- output = ugettext("Welcome to my site.")
- return HttpResponse(output)
-
-Translation works on computed values. This example is identical to the previous
-two::
-
- def my_view(request):
- words = ['Welcome', 'to', 'my', 'site.']
- output = _(' '.join(words))
- return HttpResponse(output)
-
-Translation works on variables. Again, here's an identical example::
-
- def my_view(request):
- sentence = 'Welcome to my site.'
- output = _(sentence)
- return HttpResponse(output)
-
-(The caveat with using variables or computed values, as in the previous two
-examples, is that Django's translation-string-detecting utility,
-``django-admin.py makemessages``, won't be able to find these strings. More on
-``makemessages`` later.)
-
-The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
-specified with Python's standard named-string interpolation syntax. Example::
-
- def my_view(request, m, d):
- output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}
- return HttpResponse(output)
-
-This technique lets language-specific translations reorder the placeholder
-text. For example, an English translation may be ``"Today is November 26."``,
-while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
-the month and the day placeholders swapped.
-
-For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
-instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
-have more than a single parameter. If you used positional interpolation,
-translations wouldn't be able to reorder placeholder text.
-
-Marking strings as no-op
-------------------------
-
-Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
-as a translation string without translating it. The string is later translated
-from a variable.
-
-Use this if you have constant strings that should be stored in the source
-language because they are exchanged over systems or users -- such as strings in
-a database -- but should be translated at the last possible point in time, such
-as when the string is presented to the user.
-
-Pluralization
--------------
-
-Use the function ``django.utils.translation.ungettext()`` to specify pluralized
-messages.
-
-``ungettext`` takes three arguments: the singular translation string, the plural
-translation string and the number of objects.
-
-This function is useful when you need your Django application to be localizable
-to languages where the number and complexity of `plural forms
-<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
-greater than the two forms used in English ('object' for the singular and
-'objects' for all the cases where ``count`` is different from zero, irrespective
-of its value.)
-
-For example::
-
- from django.utils.translation import ungettext
- def hello_world(request, count):
- page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
- 'count': count,
- }
- return HttpResponse(page)
-
-In this example the number of objects is passed to the translation languages as
-the ``count`` variable.
-
-Lets see a slightly more complex usage example::
-
- from django.utils.translation import ungettext
-
- count = Report.objects.count()
- if count == 1:
- name = Report._meta.verbose_name
- else:
- name = Report._meta.verbose_name_plural
-
- text = ungettext(
- 'There is %(count)d %(name)s available.',
- 'There are %(count)d %(name)s available.',
- count
- ) % {
- 'count': count,
- 'name': name
- }
-
-Here we reuse localizable, hopefully already translated literals (contained in
-the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for
-other parts of the sentence so all of it is consistently based on the
-cardinality of the elements at play.
-
-.. _pluralization-var-notes:
-
-.. note::
-
- When using this technique, make sure you use a single name for every
- extrapolated variable included in the literal. In the example above note how
- we used the ``name`` Python variable in both translation strings. This
- example would fail::
-
- from django.utils.translation import ungettext
- from myapp.models import Report
-
- count = Report.objects.count()
- d = {
- 'count': count,
- 'name': Report._meta.verbose_name,
- 'plural_name': Report._meta.verbose_name_plural
- }
- text = ungettext(
- 'There is %(count)d %(name)s available.',
- 'There are %(count)d %(plural_name)s available.',
- count
- ) % d
-
- You would get a ``a format specification for argument 'name', as in
- 'msgstr[0]', doesn't exist in 'msgid'`` error when running
- ``django-admin.py compilemessages``.
-
-.. _lazy-translations:
-
-Lazy translation
-----------------
-
-Use the function ``django.utils.translation.ugettext_lazy()`` to translate
-strings lazily -- when the value is accessed rather than when the
-``ugettext_lazy()`` function is called.
-
-For example, to translate a model's ``help_text``, do the following::
-
- from django.utils.translation import ugettext_lazy
-
- class MyThing(models.Model):
- name = models.CharField(help_text=ugettext_lazy('This is the help text'))
-
-In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
-not the actual translation. The translation itself will be done when the string
-is used in a string context, such as template rendering on the Django admin
-site.
-
-The result of a ``ugettext_lazy()`` call can be used wherever you would use a
-unicode string (an object with type ``unicode``) in Python. If you try to use
-it where a bytestring (a ``str`` object) is expected, things will not work as
-expected, since a ``ugettext_lazy()`` object doesn't know how to convert
-itself to a bytestring. You can't use a unicode string inside a bytestring,
-either, so this is consistent with normal Python behavior. For example::
-
- # This is fine: putting a unicode proxy into a unicode string.
- u"Hello %s" % ugettext_lazy("people")
-
- # This will not work, since you cannot insert a unicode object
- # into a bytestring (nor can you insert our unicode proxy there)
- "Hello %s" % ugettext_lazy("people")
-
-If you ever see output that looks like ``"hello
-<django.utils.functional...>"``, you have tried to insert the result of
-``ugettext_lazy()`` into a bytestring. That's a bug in your code.
-
-If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
-``_`` (underscore), like so::
-
- from django.utils.translation import ugettext_lazy as _
-
- class MyThing(models.Model):
- name = models.CharField(help_text=_('This is the help text'))
-
-Always use lazy translations in :doc:`Django models </topics/db/models>`.
-Field names and table names should be marked for translation (otherwise, they
-won't be translated in the admin interface). This means writing explicit
-``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,
-though, rather than relying on Django's default determination of
-``verbose_name`` and ``verbose_name_plural`` by looking at the model's class
-name::
-
- from django.utils.translation import ugettext_lazy as _
-
- class MyThing(models.Model):
- name = models.CharField(_('name'), help_text=_('This is the help text'))
- class Meta:
- verbose_name = _('my thing')
- verbose_name_plural = _('mythings')
-
-Working with lazy translation objects
--------------------------------------
-
-.. highlightlang:: python
-
-Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
-and utility functions is a common operation. When you're working with these
-objects elsewhere in your code, you should ensure that you don't accidentally
-convert them to strings, because they should be converted as late as possible
-(so that the correct locale is in effect). This necessitates the use of a
-couple of helper functions.
-
-Joining strings: string_concat()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Standard Python string joins (``''.join([...])``) will not work on lists
-containing lazy translation objects. Instead, you can use
-``django.utils.translation.string_concat()``, which creates a lazy object that
-concatenates its contents *and* converts them to strings only when the result
-is included in a string. For example::
-
- from django.utils.translation import string_concat
- ...
- name = ugettext_lazy(u'John Lennon')
- instrument = ugettext_lazy(u'guitar')
- result = string_concat(name, ': ', instrument)
-
-In this case, the lazy translations in ``result`` will only be converted to
-strings when ``result`` itself is used in a string (usually at template
-rendering time).
-
-The allow_lazy() decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Django offers many utility functions (particularly in ``django.utils``) that
-take a string as their first argument and do something to that string. These
-functions are used by template filters as well as directly in other code.
-
-If you write your own similar functions and deal with translations, you'll
-face the problem of what to do when the first argument is a lazy translation
-object. You don't want to convert it to a string immediately, because you might
-be using this function outside of a view (and hence the current thread's locale
-setting will not be correct).
-
-For cases like this, use the ``django.utils.functional.allow_lazy()``
-decorator. It modifies the function so that *if* it's called with a lazy
-translation as the first argument, the function evaluation is delayed until it
-needs to be converted to a string.
-
-For example::
-
- from django.utils.functional import allow_lazy
-
- def fancy_utility_function(s, ...):
- # Do some conversion on string 's'
- ...
- fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
-
-The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
-a number of extra arguments (``*args``) specifying the type(s) that the
-original function can return. Usually, it's enough to include ``unicode`` here
-and ensure that your function returns only Unicode strings.
-
-Using this decorator means you can write your function and assume that the
-input is a proper string, then add support for lazy translation objects at the
-end.
-
-.. _specifying-translation-strings-in-template-code:
-
-Specifying translation strings: In template code
-================================================
-
-.. highlightlang:: html+django
-
-Translations in :doc:`Django templates </topics/templates>` uses two template
-tags and a slightly different syntax than in Python code. To give your template
-access to these tags, put ``{% load i18n %}`` toward the top of your template.
-
-``trans`` template tag
-----------------------
-
-The ``{% trans %}`` template tag translates either a constant string
-(enclosed in single or double quotes) or variable content::
-
- <title>{% trans "This is the title." %}</title>
- <title>{% trans myvar %}</title>
-
-If the ``noop`` option is present, variable lookup still takes place but the
-translation is skipped. This is useful when "stubbing out" content that will
-require translation in the future::
-
- <title>{% trans "myvar" noop %}</title>
-
-Internally, inline translations use an ``ugettext`` call.
-
-In case a template var (``myvar`` above) is passed to the tag, the tag will
-first resolve such variable to a string at run-time and then look up that
-string in the message catalogs.
-
-It's not possible to mix a template variable inside a string within ``{% trans
-%}``. If your translations require strings with variables (placeholders), use
-``{% blocktrans %}`` instead.
-
-``blocktrans`` template tag
----------------------------
-
-Contrarily to the ``trans`` tag, the ``blocktrans`` tag allows you to mark
-complex sentences consisting of literals and variable content for translation
-by making use of placeholders::
-
- {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
-
-To translate a template expression -- say, accessing object attributes or
-using template filters -- you need to bind the expression to a local variable
-for use within the translation block. Examples::
-
- {% blocktrans with article.price as amount %}
- That will cost $ {{ amount }}.
- {% endblocktrans %}
-
- {% blocktrans with value|filter as myvar %}
- This will have {{ myvar }} inside.
- {% endblocktrans %}
-
-If you need to bind more than one expression inside a ``blocktrans`` tag,
-separate the pieces with ``and``::
-
- {% blocktrans with book|title as book_t and author|title as author_t %}
- This is {{ book_t }} by {{ author_t }}
- {% endblocktrans %}
-
-This tag also provides for pluralization. To use it:
-
- * Designate and bind a counter value with the name ``count``. This value will
- be the one used to select the right plural form.
-
- * Specify both the singular and plural forms separating them with the
- ``{% plural %}`` tag within the ``{% blocktrans %}`` and
- ``{% endblocktrans %}`` tags.
-
-An example::
-
- {% blocktrans count list|length as counter %}
- There is only one {{ name }} object.
- {% plural %}
- There are {{ counter }} {{ name }} objects.
- {% endblocktrans %}
-
-A more complex example::
-
- {% blocktrans with article.price as amount count i.length as years %}
- That will cost $ {{ amount }} per year.
- {% plural %}
- That will cost $ {{ amount }} per {{ years }} years.
- {% endblocktrans %}
-
-When you use both the pluralization feature and bind values to local variables
-in addition to the counter value, keep in mind that the ``blocktrans``
-construct is internally converted to an ``ungettext`` call. This means the
-same :ref:`notes regarding ungettext variables <pluralization-var-notes>`
-apply.
-
-.. _template-translation-vars:
-
-Other tags
-----------
-
-Each ``RequestContext`` has access to three translation-specific variables:
-
- * ``LANGUAGES`` is a list of tuples in which the first element is the
- :term:`language code` and the second is the language name (translated into
- the currently active locale).
-
- * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
- Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`.)
-
- * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
- right-to-left language, e.g.: Hebrew, Arabic. If False it's a
- left-to-right language, e.g.: English, French, German etc.
-
-If you don't use the ``RequestContext`` extension, you can get those values with
-three tags::
-
- {% get_current_language as LANGUAGE_CODE %}
- {% get_available_languages as LANGUAGES %}
- {% get_current_language_bidi as LANGUAGE_BIDI %}
-
-These tags also require a ``{% load i18n %}``.
-
-Translation hooks are also available within any template block tag that accepts
-constant strings. In those cases, just use ``_()`` syntax to specify a
-translation string::
-
- {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
-
-In this case, both the tag and the filter will see the already-translated
-string, so they don't need to be aware of translations.
-
-.. note::
- In this example, the translation infrastructure will be passed the string
- ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
- translated string will need to contain the comma so that the filter
- parsing code knows how to split up the arguments. For example, a German
- translator might translate the string ``"yes,no"`` as ``"ja,nein"``
- (keeping the comma intact).
-
-.. _Django templates: ../templates_python/
-
-Specifying translation strings: In JavaScript code
-==================================================
-
-Adding translations to JavaScript poses some problems:
-
- * JavaScript code doesn't have access to a ``gettext`` implementation.
-
- * JavaScript code doesn't have access to .po or .mo files; they need to be
- delivered by the server.
-
- * The translation catalogs for JavaScript should be kept as small as
- possible.
-
-Django provides an integrated solution for these problems: It passes the
-translations into JavaScript, so you can call ``gettext``, etc., from within
-JavaScript.
-
-The ``javascript_catalog`` view
--------------------------------
-
-.. module:: django.views.i18n
-
-.. function:: javascript_catalog(request, domain='djangojs', packages=None)
-
-The main solution to these problems is the :meth:`django.views.i18n.javascript_catalog`
-view, which sends out a JavaScript code library with functions that mimic the
-``gettext`` interface, plus an array of translation strings. Those translation
-strings are taken from the application, project or Django core, according to what
-you specify in either the info_dict or the URL.
-
-You hook it up like this::
-
- js_info_dict = {
- 'packages': ('your.app.package',),
- }
-
- urlpatterns = patterns('',
- (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
- )
-
-Each string in ``packages`` should be in Python dotted-package syntax (the
-same format as the strings in ``INSTALLED_APPS``) and should refer to a package
-that contains a ``locale`` directory. If you specify multiple packages, all
-those catalogs are merged into one catalog. This is useful if you have
-JavaScript that uses strings from different applications.
-
-By default, the view uses the ``djangojs`` gettext domain. This can be
-changed by altering the ``domain`` argument.
-
-You can make the view dynamic by putting the packages into the URL pattern::
-
- urlpatterns = patterns('',
- (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
- )
-
-With this, you specify the packages as a list of package names delimited by '+'
-signs in the URL. This is especially useful if your pages use code from
-different apps and this changes often and you don't want to pull in one big
-catalog file. As a security measure, these values can only be either
-``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
-
-Using the JavaScript translation catalog
-----------------------------------------
-
-To use the catalog, just pull in the dynamically generated script like this::
-
- <script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
-
-This uses reverse URL lookup to find the URL of the JavaScript catalog view.
-When the catalog is loaded, your JavaScript code can use the standard
-``gettext`` interface to access it::
-
- document.write(gettext('this is to be translated'));
-
-There is also an ``ngettext`` interface::
-
- var object_cnt = 1 // or 0, or 2, or 3, ...
- s = ngettext('literal for the singular case',
- 'literal for the plural case', object_cnt);
-
-and even a string interpolation function::
-
- function interpolate(fmt, obj, named);
-
-The interpolation syntax is borrowed from Python, so the ``interpolate``
-function supports both positional and named interpolation:
-
- * Positional interpolation: ``obj`` contains a JavaScript Array object
- whose elements values are then sequentially interpolated in their
- corresponding ``fmt`` placeholders in the same order they appear.
- For example::
-
- fmts = ngettext('There is %s object. Remaining: %s',
- 'There are %s objects. Remaining: %s', 11);
- s = interpolate(fmts, [11, 20]);
- // s is 'There are 11 objects. Remaining: 20'
-
- * Named interpolation: This mode is selected by passing the optional
- boolean ``named`` parameter as true. ``obj`` contains a JavaScript
- object or associative array. For example::
-
- d = {
- count: 10,
- total: 50
- };
-
- fmts = ngettext('Total: %(total)s, there is %(count)s object',
- 'there are %(count)s of a total of %(total)s objects', d.count);
- s = interpolate(fmts, d, true);
-
-You shouldn't go over the top with string interpolation, though: this is still
-JavaScript, so the code has to make repeated regular-expression substitutions.
-This isn't as fast as string interpolation in Python, so keep it to those
-cases where you really need it (for example, in conjunction with ``ngettext``
-to produce proper pluralizations).
-
-The ``set_language`` redirect view
-==================================
-
-.. function:: set_language(request)
-
-As a convenience, Django comes with a view, :meth:`django.views.i18n.set_language`,
-that sets a user's language preference and redirects back to the previous page.
-
-Activate this view by adding the following line to your URLconf::
-
- (r'^i18n/', include('django.conf.urls.i18n')),
-
-(Note that this example makes the view available at ``/i18n/setlang/``.)
-
-The view expects to be called via the ``POST`` method, with a ``language``
-parameter set in request. If session support is enabled, the view
-saves the language choice in the user's session. Otherwise, it saves the
-language choice in a cookie that is by default named ``django_language``.
-(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
-
-After setting the language choice, Django redirects the user, following this
-algorithm:
-
- * Django looks for a ``next`` parameter in the ``POST`` data.
- * If that doesn't exist, or is empty, Django tries the URL in the
- ``Referrer`` header.
- * If that's empty -- say, if a user's browser suppresses that header --
- then the user will be redirected to ``/`` (the site root) as a fallback.
-
-Here's example HTML template code:
-
-.. code-block:: html+django
-
- <form action="/i18n/setlang/" method="post">
- {% csrf_token %}
- <input name="next" type="hidden" value="/next/page/" />
- <select name="language">
- {% for lang in LANGUAGES %}
- <option value="{{ lang.0 }}">{{ lang.1 }}</option>
- {% endfor %}
- </select>
- <input type="submit" value="Go" />
- </form>