Commit eb96665b authored by Jannis Leidel's avatar Jannis Leidel
Browse files

[1.3.X] Added a few cross references to the i18n docs and documented pgettext and colleagues.

Backport from trunk (r16403).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16404 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 4f215cfc
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -315,6 +315,48 @@ Atom1Feed

    Spec: http://atompub.org/2005/07/11/draft-ietf-atompub-format-10.html

``django.utils.functional``
===========================

.. module:: django.utils.functional
    :synopsis: Functional programming tools.

.. function:: allow_lazy(func, *resultclasses)

    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.


``django.utils.http``
=====================

@@ -428,14 +470,23 @@ For a complete discussion on the usage of the following see the

    Translates ``message`` and returns it in a unicode string

.. function:: pgettext(context, message)

    Translates ``message`` given the ``context`` and returns
    it in a unicode string.

    For more information, see :ref:`contextual-markers`.

.. function:: gettext_lazy(message)
.. function:: ugettext_lazy(message)
.. function:: pgettext_lazy(context, message)

    Same as the non-lazy versions above, but using lazy execution.

    See :ref:`lazy translations documentation <lazy-translations>`.

.. function:: gettext_noop(message)
.. function:: ugettext_noop(message)

    Marks strings for translation but doesn't translate them now. This can be
    used to store strings in global variables that should stay in the base
@@ -452,8 +503,14 @@ For a complete discussion on the usage of the following see the
    Translates ``singular`` and ``plural`` and returns the appropriate string
    based on ``number`` in a unicode string.

.. function:: npgettext(context, singular, plural, number)

    Translates ``singular`` and ``plural`` and returns the appropriate string
    based on ``number`` and the ``context`` in a unicode string.

.. function:: ngettext_lazy(singular, plural, number)
.. function:: ungettext_lazy(singular, plural, number)
.. function:: npgettext_lazy(singular, plural, number)

    Same as the non-lazy versions above, but using lazy execution.

+48 −63
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
Internationalization
====================

.. module:: django.utils.translation

Overview
========

@@ -24,19 +26,22 @@ 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.
Specify a translation string by using the function
:func:`~django.utils.translation.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.
      1. For international character set (Unicode) support,
         :func:`~django.utils.translation.ugettext` is more useful than
         ``gettext()``. Sometimes, you should be using
         :func:`~django.utils.translation.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
@@ -127,20 +132,20 @@ displayed by most translation tools.
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 the function :func:`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.
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.
Use the function :func:`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.
@@ -155,14 +160,18 @@ 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) % {
        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.
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::

@@ -226,8 +235,8 @@ Contextual markers
Sometimes words have several meanings, such as ``"May"`` in English, which
refers to a month name and to a verb. To enable translators to translate
these words correctly in different contexts, you can use the
``django.utils.translation.pgettext()`` function, or the
``django.utils.translation.npgettext()`` function if the string needs
:func:`django.utils.translation.pgettext()` function, or the
:func:`django.utils.translation.npgettext()` function if the string needs
pluralization. Both take a context string as the first variable.

In the resulting .po file, the string will then appear as often as there are
@@ -241,6 +250,14 @@ For example::

    month = pgettext("month name", "May")

or::

    from django.utils.translation import pgettext_lazy

    class MyThing(models.Model):
        name = models.CharField(help_text=pgettext_lazy(
            'help text for MyThing model', 'This is the help text'))

will appear in the .po file as:

.. code-block:: po
@@ -254,7 +271,7 @@ will appear in the .po file as:
Lazy translation
----------------

Use the function ``django.utils.translation.ugettext_lazy()`` to translate
Use the function :func:`django.utils.translation.ugettext_lazy()` to translate
strings lazily -- when the value is accessed rather than when the
``ugettext_lazy()`` function is called.

@@ -308,6 +325,7 @@ name::

    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')
@@ -360,9 +378,9 @@ 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::
:func:`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
    ...
@@ -374,47 +392,13 @@ 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.
Localized names of languages
============================

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.
.. function:: get_language_info

.. versionadded:: 1.3

Localized names of languages
============================

The ``get_language_info()`` function provides detailed information about
languages::

@@ -456,7 +440,8 @@ require translation in the future::

    <title>{% trans "myvar" noop %}</title>

Internally, inline translations use an ``ugettext`` call.
Internally, inline translations use an
:func:`~django.utils.translation.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
@@ -777,7 +762,7 @@ The ``set_language`` redirect view

.. function:: set_language(request)

As a convenience, Django comes with a view, :meth:`django.views.i18n.set_language`,
As a convenience, Django comes with a view, :func:`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::