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
This commit is contained in:
Jannis Leidel 2010-02-21 23:43:28 +00:00
parent b459f5b7e3
commit 84f8213d74
4 changed files with 29 additions and 14 deletions

View File

@ -551,8 +551,8 @@ class FilterExpression(object):
elif var_arg: elif var_arg:
args.append((True, Variable(var_arg))) args.append((True, Variable(var_arg)))
filter_func = parser.find_filter(filter_name) filter_func = parser.find_filter(filter_name)
self.args_check(filter_name,filter_func, args) self.args_check(filter_name, filter_func, args)
filters.append( (filter_func,args)) filters.append((filter_func, args))
upto = match.end() upto = match.end()
if upto != len(token): if upto != len(token):
raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)) raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token))

View File

@ -3,10 +3,6 @@
import sys import sys
import re import re
from itertools import cycle as itertools_cycle 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 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 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

View File

@ -34,16 +34,16 @@ class GetCurrentLanguageBidiNode(Node):
return '' return ''
class TranslateNode(Node): class TranslateNode(Node):
def __init__(self, value, noop): def __init__(self, filter_expression, noop):
self.value = Variable(value)
self.noop = 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): def render(self, context):
value = self.value.resolve(context) self.filter_expression.var.translate = not self.noop
if self.noop: output = self.filter_expression.resolve(context)
return value return _render_value_in_context(output, context)
else:
return _render_value_in_context(translation.ugettext(value), context)
class BlockTranslateNode(Node): class BlockTranslateNode(Node):
def __init__(self, extra_context, singular, plural=None, countervar=None, def __init__(self, extra_context, singular, plural=None, countervar=None,
@ -174,6 +174,20 @@ def do_translate(parser, token):
class TranslateParser(TokenParser): class TranslateParser(TokenParser):
def top(self): def top(self):
value = self.value() 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.more():
if self.tag() == 'noop': if self.tag() == 'noop':
noop = True noop = True
@ -183,7 +197,7 @@ def do_translate(parser, token):
noop = False noop = False
return (value, noop) return (value, noop)
value, noop = TranslateParser(token.contents).top() value, noop = TranslateParser(token.contents).top()
return TranslateNode(value, noop) return TranslateNode(parser.compile_filter(value), noop)
def do_block_translate(parser, token): def do_block_translate(parser, token):
""" """

View File

@ -907,6 +907,11 @@ class Templates(unittest.TestCase):
'i18n21': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': mark_safe('a & b')}, u'a & b'), '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'), '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 ################################### ### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')), 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),