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.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11164 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2009-07-03 05:42:09 +00:00
parent 6ed0345092
commit 037b833f2e
1 changed files with 75 additions and 6 deletions

View File

@ -223,7 +223,19 @@ Pluralization
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
Use the function ``django.utils.translation.ungettext()`` to specify pluralized 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 from django.utils.translation import ungettext
def hello_world(request, count): def hello_world(request, count):
@ -232,9 +244,61 @@ messages. Example::
} }
return HttpResponse(page) return HttpResponse(page)
``ungettext`` takes three arguments: the singular translation string, the plural In this example the number of objects is passed to the translation languages as
translation string and the number of objects (which is passed to the the ``count`` variable.
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 In template code
---------------- ----------------
@ -257,6 +321,8 @@ content that will require translation in the future::
<title>{% trans "myvar" noop %}</title> <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 It's not possible to mix a template variable inside a string within ``{% trans
%}``. If your translations require strings with variables (placeholders), use %}``. If your translations require strings with variables (placeholders), use
``{% blocktrans %}``:: ``{% blocktrans %}``::
@ -288,8 +354,11 @@ To pluralize, specify both the singular and plural forms with the
There are {{ counter }} {{ name }} objects. There are {{ counter }} {{ name }} objects.
{% endblocktrans %} {% endblocktrans %}
Internally, all block and inline translations use the appropriate When you use the pluralization feature and bind additional values to local
``ugettext`` / ``ungettext`` call. 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: Each ``RequestContext`` has access to three translation-specific variables: