From 037b833f2e445331100b0a6e85d2e589a57d5c94 Mon Sep 17 00:00:00 2001
From: Russell Keith-Magee <russell@keith-magee.com>
Date: Fri, 3 Jul 2009 05:42:09 +0000
Subject: [PATCH] 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
---
 docs/topics/i18n.txt | 81 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 75 insertions(+), 6 deletions(-)

diff --git a/docs/topics/i18n.txt b/docs/topics/i18n.txt
index 86c03221aa..7bf51c11c5 100644
--- a/docs/topics/i18n.txt
+++ b/docs/topics/i18n.txt
@@ -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: