Fixed #16717 -- Added ability to store result of trans template tag in context variable.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16712 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-08-30 12:09:45 +00:00
parent 5ed2cf03bb
commit 3256862f5f
4 changed files with 57 additions and 10 deletions

View File

@ -70,8 +70,9 @@ class GetCurrentLanguageBidiNode(Node):
class TranslateNode(Node): class TranslateNode(Node):
def __init__(self, filter_expression, noop): def __init__(self, filter_expression, noop, asvar=None):
self.noop = noop self.noop = noop
self.asvar = asvar
self.filter_expression = filter_expression self.filter_expression = filter_expression
if isinstance(self.filter_expression.var, basestring): if isinstance(self.filter_expression.var, basestring):
self.filter_expression.var = Variable(u"'%s'" % self.filter_expression.var) self.filter_expression.var = Variable(u"'%s'" % self.filter_expression.var)
@ -79,7 +80,12 @@ class TranslateNode(Node):
def render(self, context): def render(self, context):
self.filter_expression.var.translate = not self.noop self.filter_expression.var.translate = not self.noop
output = self.filter_expression.resolve(context) 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): class BlockTranslateNode(Node):
@ -296,16 +302,21 @@ def do_translate(parser, token):
elif value[-1] == "'": elif value[-1] == "'":
value = '"%s"' % value[1:-1].replace('"','\\"') value = '"%s"' % value[1:-1].replace('"','\\"')
if self.more(): noop = False
if self.tag() == 'noop': asvar = None
while self.more():
tag = self.tag()
if tag == 'noop':
noop = True noop = True
elif tag == 'as':
asvar = self.tag()
else: else:
raise TemplateSyntaxError("only option for 'trans' is 'noop'") raise TemplateSyntaxError(
else: "only options for 'trans' are 'noop' and 'as VAR.")
noop = False return (value, noop, asvar)
return (value, noop) value, noop, asvar = TranslateParser(token.contents).top()
value, noop = TranslateParser(token.contents).top() return TranslateNode(parser.compile_filter(value), noop, asvar)
return TranslateNode(parser.compile_filter(value), noop)
@register.tag("blocktrans") @register.tag("blocktrans")
def do_block_translate(parser, token): def do_block_translate(parser, token):

View File

@ -283,6 +283,10 @@ Django 1.4 also includes several smaller improvements worth noting:
about :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` for more about :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` for more
information. 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-1.4:
Backwards incompatible changes in 1.4 Backwards incompatible changes in 1.4

View File

@ -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 %}``. If your translations require strings with variables (placeholders), use
``{% blocktrans %}`` instead. ``{% 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 %}
<title>{{ the_title }}</title>
<meta name="description" content="{{ 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 %}
<h1>
<a href="/" title="{% blocktrans %}Back to '{{ race }}' homepage{% endblocktrans %}">{{ race }}</a>
</h1>
<p>
{% for stage in tour_stages %}
{% cycle start end %}: {{ stage }}{% if forloop.counter|divisibleby:2 %}<br />{% else %}, {% endif %}
{% endfor %}
</p>
.. templatetag:: blocktrans .. templatetag:: blocktrans
``blocktrans`` template tag ``blocktrans`` template tag

View File

@ -1294,6 +1294,12 @@ class Templates(unittest.TestCase):
# blocktrans handling of variables which are not in the context. # blocktrans handling of variables which are not in the context.
'i18n34': ('{% load i18n %}{% blocktrans %}{{ missing }}{% endblocktrans %}', {}, u''), '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 ################################### ### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')), 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),