diff --git a/docs/i18n.txt b/docs/i18n.txt index 8da19cd242..c4bcab4d74 100644 --- a/docs/i18n.txt +++ b/docs/i18n.txt @@ -338,7 +338,7 @@ 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 +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 @@ -789,7 +789,7 @@ JavaScript that uses strings from different applications. You can make the view dynamic by putting the packages into the URL pattern:: urlpatterns = patterns('', - (r'^jsi18n/(?P\S+?)/$, 'django.views.i18n.javascript_catalog'), + (r'^jsi18n/(?P\S+?)/$', 'django.views.i18n.javascript_catalog'), ) With this, you specify the packages as a list of package names delimited by '+' @@ -811,24 +811,47 @@ interface to access it:: document.write(gettext('this is to be translated')); -There even is a ``ungettext`` interface and a string interpolation function:: +There is also an ``ngettext`` interface:: - d = { - count: 10 - }; - s = interpolate(ungettext('this is %(count)s object', 'this are %(count)s objects', d.count), d); + var object_cnt = 1 // or 0, or 2, or 3, ... + s = ngettext('literal for the singular case', + 'literal for the plural case', object_cnt); -The ``interpolate`` function supports both positional interpolation and named -interpolation. So the above could have been written as:: +and even a string interpolation function:: - s = interpolate(ungettext('this is %s object', 'this are %s objects', 11), [11]); + function interpolate(fmt, obj, named); -The interpolation syntax is borrowed from Python. You shouldn't go over the top -with string interpolation, though: this is still JavaScript, so the code will -have to do 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 ``ungettext`` to produce proper -pluralizations). +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). Creating JavaScript translation catalogs ----------------------------------------