Loading django/template/__init__.py +14 −5 Original line number Diff line number Diff line Loading @@ -790,6 +790,18 @@ class TextNode(Node): def render(self, context): return self.s def _render_value_in_context(value, context): """ Converts any value to a string to become part of a rendered template. This means escaping, if required, and conversion to a unicode object. If value is a string, it is expected to have already been translated. """ value = force_unicode(value) if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData): return escape(value) else: return value class VariableNode(Node): def __init__(self, filter_expression): self.filter_expression = filter_expression Loading @@ -799,15 +811,12 @@ class VariableNode(Node): def render(self, context): try: output = force_unicode(self.filter_expression.resolve(context)) output = self.filter_expression.resolve(context) except UnicodeDecodeError: # Unicode conversion can fail sometimes for reasons out of our # control (e.g. exception rendering). In that case, we fail quietly. return '' if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): return force_unicode(escape(output)) else: return force_unicode(output) return _render_value_in_context(output, context) def generic_tag_compiler(params, defaults, name, node_class, parser, token): "Returns a template.Node subclass." Loading django/templatetags/i18n.py +3 −3 Original line number Diff line number Diff line import re from django.template import Node, Variable, VariableNode from django.template import Node, Variable, VariableNode, _render_value_in_context from django.template import TemplateSyntaxError, TokenParser, Library from django.template import TOKEN_TEXT, TOKEN_VAR from django.utils import translation Loading Loading @@ -43,7 +43,7 @@ class TranslateNode(Node): if self.noop: return value else: return translation.ugettext(value) return _render_value_in_context(translation.ugettext(value), context) class BlockTranslateNode(Node): def __init__(self, extra_context, singular, plural=None, countervar=None, Loading Loading @@ -82,7 +82,7 @@ class BlockTranslateNode(Node): result = translation.ugettext(singular) # Escape all isolated '%' before substituting in the context. result = re.sub(u'%(?!\()', u'%%', result) data = dict([(v, force_unicode(context[v])) for v in vars]) data = dict([(v, _render_value_in_context(context[v], context)) for v in vars]) context.pop() return result % data Loading tests/regressiontests/templates/tests.py +8 −4 Original line number Diff line number Diff line Loading @@ -825,12 +825,16 @@ class Templates(unittest.TestCase): 'i18n14': ('{% cycle "foo" _("Password") _(\'Password\') as c %} {% cycle c %} {% cycle c %}', {'LANGUAGE_CODE': 'de'}, 'foo Passwort Passwort'), 'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 'de', 'absent': ""}, 'Passwort'), 'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'), 'i18n17': ('{{ _("") }}', {'LANGUAGE_CODE': 'de'}, ''), 'i18n16a': ('{{ _("") }}', {'LANGUAGE_CODE': 'de'}, ''), # Escaping inside blocktrans works as if it was directly in the # Escaping inside blocktrans and trans works as if it was directly in the # template. 'i18n18': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n19': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n19': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': 'a & b'}, u'a & b'), 'i18n20': ('{% load i18n %}{% trans andrew %}', {'andrew': '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'), ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### Loading Loading
django/template/__init__.py +14 −5 Original line number Diff line number Diff line Loading @@ -790,6 +790,18 @@ class TextNode(Node): def render(self, context): return self.s def _render_value_in_context(value, context): """ Converts any value to a string to become part of a rendered template. This means escaping, if required, and conversion to a unicode object. If value is a string, it is expected to have already been translated. """ value = force_unicode(value) if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData): return escape(value) else: return value class VariableNode(Node): def __init__(self, filter_expression): self.filter_expression = filter_expression Loading @@ -799,15 +811,12 @@ class VariableNode(Node): def render(self, context): try: output = force_unicode(self.filter_expression.resolve(context)) output = self.filter_expression.resolve(context) except UnicodeDecodeError: # Unicode conversion can fail sometimes for reasons out of our # control (e.g. exception rendering). In that case, we fail quietly. return '' if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): return force_unicode(escape(output)) else: return force_unicode(output) return _render_value_in_context(output, context) def generic_tag_compiler(params, defaults, name, node_class, parser, token): "Returns a template.Node subclass." Loading
django/templatetags/i18n.py +3 −3 Original line number Diff line number Diff line import re from django.template import Node, Variable, VariableNode from django.template import Node, Variable, VariableNode, _render_value_in_context from django.template import TemplateSyntaxError, TokenParser, Library from django.template import TOKEN_TEXT, TOKEN_VAR from django.utils import translation Loading Loading @@ -43,7 +43,7 @@ class TranslateNode(Node): if self.noop: return value else: return translation.ugettext(value) return _render_value_in_context(translation.ugettext(value), context) class BlockTranslateNode(Node): def __init__(self, extra_context, singular, plural=None, countervar=None, Loading Loading @@ -82,7 +82,7 @@ class BlockTranslateNode(Node): result = translation.ugettext(singular) # Escape all isolated '%' before substituting in the context. result = re.sub(u'%(?!\()', u'%%', result) data = dict([(v, force_unicode(context[v])) for v in vars]) data = dict([(v, _render_value_in_context(context[v], context)) for v in vars]) context.pop() return result % data Loading
tests/regressiontests/templates/tests.py +8 −4 Original line number Diff line number Diff line Loading @@ -825,12 +825,16 @@ class Templates(unittest.TestCase): 'i18n14': ('{% cycle "foo" _("Password") _(\'Password\') as c %} {% cycle c %} {% cycle c %}', {'LANGUAGE_CODE': 'de'}, 'foo Passwort Passwort'), 'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 'de', 'absent': ""}, 'Passwort'), 'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'), 'i18n17': ('{{ _("") }}', {'LANGUAGE_CODE': 'de'}, ''), 'i18n16a': ('{{ _("") }}', {'LANGUAGE_CODE': 'de'}, ''), # Escaping inside blocktrans works as if it was directly in the # Escaping inside blocktrans and trans works as if it was directly in the # template. 'i18n18': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n19': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 'i18n19': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': 'a & b'}, u'a & b'), 'i18n20': ('{% load i18n %}{% trans andrew %}', {'andrew': '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'), ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### Loading