From 84f8213d74817b8d5aaf81dfa611e919d5266360 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Sun, 21 Feb 2010 23:43:28 +0000 Subject: [PATCH] Fixed #5972 - Allow the template filters to be used with the trans tag. Thanks for the initial patch, Dmitri Fedortchenko. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12472 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/template/__init__.py | 4 ++-- django/template/defaulttags.py | 4 ---- django/templatetags/i18n.py | 30 +++++++++++++++++------- tests/regressiontests/templates/tests.py | 5 ++++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/django/template/__init__.py b/django/template/__init__.py index eba2429928..66c415a8c4 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -551,8 +551,8 @@ class FilterExpression(object): elif var_arg: args.append((True, Variable(var_arg))) filter_func = parser.find_filter(filter_name) - self.args_check(filter_name,filter_func, args) - filters.append( (filter_func,args)) + self.args_check(filter_name, filter_func, args) + filters.append((filter_func, args)) upto = match.end() if upto != len(token): raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index f1b1de795b..124841c614 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -3,10 +3,6 @@ import sys import re from itertools import cycle as itertools_cycle -try: - reversed -except NameError: - from django.utils.itercompat import reversed # Python 2.3 fallback from django.template import Node, NodeList, Template, Context, Variable from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 49903bac9c..10ac900041 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -34,16 +34,16 @@ class GetCurrentLanguageBidiNode(Node): return '' class TranslateNode(Node): - def __init__(self, value, noop): - self.value = Variable(value) + def __init__(self, filter_expression, noop): self.noop = noop + self.filter_expression = filter_expression + if isinstance(self.filter_expression.var, basestring): + self.filter_expression.var = Variable(u"'%s'" % self.filter_expression.var) def render(self, context): - value = self.value.resolve(context) - if self.noop: - return value - else: - return _render_value_in_context(translation.ugettext(value), context) + self.filter_expression.var.translate = not self.noop + output = self.filter_expression.resolve(context) + return _render_value_in_context(output, context) class BlockTranslateNode(Node): def __init__(self, extra_context, singular, plural=None, countervar=None, @@ -174,6 +174,20 @@ def do_translate(parser, token): class TranslateParser(TokenParser): def top(self): value = self.value() + + # Backwards Compatiblity fix: + # FilterExpression does not support single-quoted strings, + # so we make a cheap localized fix in order to maintain + # backwards compatibility with existing uses of ``trans`` + # where single quote use is supported. + if value[0] == "'": + pos = None + m = re.match("^'([^']+)'(\|.*$)",value) + if m: + value = '"%s"%s' % (m.group(1).replace('"','\\"'),m.group(2)) + elif value[-1] == "'": + value = '"%s"' % value[1:-1].replace('"','\\"') + if self.more(): if self.tag() == 'noop': noop = True @@ -183,7 +197,7 @@ def do_translate(parser, token): noop = False return (value, noop) value, noop = TranslateParser(token.contents).top() - return TranslateNode(value, noop) + return TranslateNode(parser.compile_filter(value), noop) def do_block_translate(parser, token): """ diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 925fc57084..22e4e45d98 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -907,6 +907,11 @@ class Templates(unittest.TestCase): 'i18n21': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': mark_safe('a & b')}, u'a & b'), 'i18n22': ('{% load i18n %}{% trans andrew %}', {'andrew': mark_safe('a & b')}, u'a & b'), + # Use filters with the {% trans %} tag, #5972 + 'i18n23': ('{% load i18n %}{% trans "Page not found"|capfirst|slice:"6:" %}', {'LANGUAGE_CODE': 'de'}, u'nicht gefunden'), + 'i18n24': ("{% load i18n %}{% trans 'Page not found'|upper %}", {'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'), + 'i18n25': ('{% load i18n %}{% trans somevar|upper %}', {'somevar': 'Page not found', 'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'), + ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),