Commit 45411379 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

[1.0.X] Fixed #10604 -- Added note on the limitation of ungettext, especially...

[1.0.X] Fixed #10604 -- Added note on the limitation of ungettext, especially as relating to the {% blocktrans %} tag. Thanks to bartTC for the report, and Ramiro Morales for the patch.

Merge of r11164 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@11167 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 9219741e
Loading
Loading
Loading
Loading
+75 −6
Original line number Diff line number Diff line
@@ -223,7 +223,19 @@ Pluralization
~~~~~~~~~~~~~

Use the function ``django.utils.translation.ungettext()`` to specify pluralized
messages. Example::
messages.

``ungettext`` takes three arguments: the singular translation string, the plural
translation string and the number of objects.

This function is useful when your need you 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):
@@ -232,9 +244,61 @@ messages. Example::
        }
        return HttpResponse(page)

``ungettext`` takes three arguments: the singular translation string, the plural
translation string and the number of objects (which 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::

    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`` or a ``KeyError`` Python exception at
    runtime.

In template code
----------------
@@ -257,6 +321,8 @@ content that will require translation in the future::

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

Internally, inline translations use an ``ugettext`` call.

It's not possible to mix a template variable inside a string within ``{% trans
%}``. If your translations require strings with variables (placeholders), use
``{% blocktrans %}``::
@@ -288,8 +354,11 @@ To pluralize, specify both the singular and plural forms with the
    There are {{ counter }} {{ name }} objects.
    {% endblocktrans %}

Internally, all block and inline translations use the appropriate
``ugettext`` / ``ungettext`` call.
When you use the pluralization feature and bind additional values to local
variables apart from the counter value that selects the translated literal to be
used, have 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.

Each ``RequestContext`` has access to three translation-specific variables: