diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index c7202e252b3..8fc312c0664 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -70,8 +70,9 @@ class GetCurrentLanguageBidiNode(Node): class TranslateNode(Node): - def __init__(self, filter_expression, noop): + def __init__(self, filter_expression, noop, asvar=None): self.noop = noop + self.asvar = asvar self.filter_expression = filter_expression if isinstance(self.filter_expression.var, basestring): self.filter_expression.var = Variable(u"'%s'" % self.filter_expression.var) @@ -79,7 +80,12 @@ class TranslateNode(Node): def render(self, context): self.filter_expression.var.translate = not self.noop output = self.filter_expression.resolve(context) - return _render_value_in_context(output, context) + value = _render_value_in_context(output, context) + if self.asvar: + context[self.asvar] = value + return '' + else: + return value class BlockTranslateNode(Node): @@ -296,16 +302,21 @@ def do_translate(parser, token): elif value[-1] == "'": value = '"%s"' % value[1:-1].replace('"','\\"') - if self.more(): - if self.tag() == 'noop': + noop = False + asvar = None + + while self.more(): + tag = self.tag() + if tag == 'noop': noop = True + elif tag == 'as': + asvar = self.tag() else: - raise TemplateSyntaxError("only option for 'trans' is 'noop'") - else: - noop = False - return (value, noop) - value, noop = TranslateParser(token.contents).top() - return TranslateNode(parser.compile_filter(value), noop) + raise TemplateSyntaxError( + "only options for 'trans' are 'noop' and 'as VAR.") + return (value, noop, asvar) + value, noop, asvar = TranslateParser(token.contents).top() + return TranslateNode(parser.compile_filter(value), noop, asvar) @register.tag("blocktrans") def do_block_translate(parser, token): diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 49204c4f1c6..4e59acff3a4 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -283,6 +283,10 @@ Django 1.4 also includes several smaller improvements worth noting: about :ref:`the 403 (HTTP Forbidden) view` for more information. +* The :ttag:`trans` template tag now takes an optional ``as`` argument to + be able to retrieve a translation string without displaying it but setting + a template context variable instead. + .. _backwards-incompatible-changes-1.4: Backwards incompatible changes in 1.4 diff --git a/docs/topics/i18n/internationalization.txt b/docs/topics/i18n/internationalization.txt index de928445265..176ad7fb43e 100644 --- a/docs/topics/i18n/internationalization.txt +++ b/docs/topics/i18n/internationalization.txt @@ -451,6 +451,32 @@ It's not possible to mix a template variable inside a string within ``{% trans %}``. If your translations require strings with variables (placeholders), use ``{% blocktrans %}`` instead. +.. versionchanged:: 1.4 + +If you'd like to retrieve a translated string without displaying it, you can +use the following syntax:: + + {% trans "This is the title" as the_title %} + + {{ the_title }} + + +In practice you'll use this to get strings that are used in multiple places +or should be used as arguments for other template tags or filters:: + + {% trans "starting point" as start %} + {% trans "end point" as end %} + {% trans "La Grande Boucle" as race %} + +

+ {{ race }} +

+

+ {% for stage in tour_stages %} + {% cycle start end %}: {{ stage }}{% if forloop.counter|divisibleby:2 %}
{% else %}, {% endif %} + {% endfor %} +

+ .. templatetag:: blocktrans ``blocktrans`` template tag diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 8c722b8bae6..2064f139833 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -1294,6 +1294,12 @@ class Templates(unittest.TestCase): # blocktrans handling of variables which are not in the context. 'i18n34': ('{% load i18n %}{% blocktrans %}{{ missing }}{% endblocktrans %}', {}, u''), + # trans tag with as var + 'i18n35': ('{% load i18n %}{% trans "Page not found" as page_not_found %}{{ page_not_found }}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"), + 'i18n36': ('{% load i18n %}{% trans "Page not found" noop as page_not_found %}{{ page_not_found }}', {'LANGUAGE_CODE': 'de'}, "Page not found"), + 'i18n36': ('{% load i18n %}{% trans "Page not found" as page_not_found noop %}{{ page_not_found }}', {'LANGUAGE_CODE': 'de'}, "Page not found"), + 'i18n37': ('{% load i18n %}{% trans "Page not found" as page_not_found %}{% blocktrans %}Error: {{ page_not_found }}{% endblocktrans %}', {'LANGUAGE_CODE': 'de'}, "Error: Seite nicht gefunden"), + ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),