Author: mtredinnick
Date: 2007-11-17 06:12:18 -0600 (Sat, 17 Nov 2007)
New Revision: 6682

Modified:
   django/trunk/django/templatetags/i18n.py
   django/trunk/tests/regressiontests/templates/tests.py
Log:
Fixed a few problems with variable resolving inside of blocktrans tags. A 
couple of these were exposed by the auto-escaping changes, but I suspect the 
other one has been hiding in plain sight for a while.

Fixed #5952, #5953


Modified: django/trunk/django/templatetags/i18n.py
===================================================================
--- django/trunk/django/templatetags/i18n.py    2007-11-17 12:11:54 UTC (rev 
6681)
+++ django/trunk/django/templatetags/i18n.py    2007-11-17 12:12:18 UTC (rev 
6682)
@@ -1,9 +1,10 @@
 import re
 
-from django.template import Node, Variable
+from django.template import Node, Variable, VariableNode
 from django.template import TemplateSyntaxError, TokenParser, Library
 from django.template import TOKEN_TEXT, TOKEN_VAR
 from django.utils import translation
+from django.utils.encoding import force_unicode
 
 register = Library()
 
@@ -45,7 +46,8 @@
             return translation.ugettext(value)
 
 class BlockTranslateNode(Node):
-    def __init__(self, extra_context, singular, plural=None, countervar=None, 
counter=None):
+    def __init__(self, extra_context, singular, plural=None, countervar=None,
+            counter=None):
         self.extra_context = extra_context
         self.singular = singular
         self.plural = plural
@@ -54,29 +56,32 @@
 
     def render_token_list(self, tokens):
         result = []
+        vars = []
         for token in tokens:
             if token.token_type == TOKEN_TEXT:
                 result.append(token.contents)
             elif token.token_type == TOKEN_VAR:
-                result.append('%%(%s)s' % token.contents)
-        return ''.join(result)
+                result.append(u'%%(%s)s' % token.contents)
+                vars.append(token.contents)
+        return ''.join(result), vars
 
     def render(self, context):
         context.push()
-        for var,val in self.extra_context.items():
-            context[var] = val.resolve(context)
-        singular = self.render_token_list(self.singular)
+        for var, val in self.extra_context.items():
+            context[var] = val.render(context)
+        singular, vars = self.render_token_list(self.singular)
         if self.plural and self.countervar and self.counter:
             count = self.counter.resolve(context)
             context[self.countervar] = count
-            plural = self.render_token_list(self.plural)
+            plural = self.render_token_list(self.plural)[0]
             result = translation.ungettext(singular, plural, count)
         else:
             result = translation.ugettext(singular)
         # Escape all isolated '%' before substituting in the context.
-        result = re.sub('%(?!\()', '%%', result) % context
+        result = re.sub(u'%(?!\()', u'%%', result)
+        data = dict([(v, force_unicode(context[v])) for v in vars])
         context.pop()
-        return result
+        return result % data
 
 def do_get_available_languages(parser, token):
     """
@@ -198,7 +203,6 @@
     This is much like ngettext, only in template syntax.
     """
     class BlockTranslateParser(TokenParser):
-
         def top(self):
             countervar = None
             counter = None
@@ -209,7 +213,8 @@
                     value = self.value()
                     if self.tag() != 'as':
                         raise TemplateSyntaxError, "variable bindings in 
'blocktrans' must be 'with value as variable'"
-                    extra_context[self.tag()] = parser.compile_filter(value)
+                    extra_context[self.tag()] = VariableNode(
+                            parser.compile_filter(value))
                 elif tag == 'count':
                     counter = parser.compile_filter(self.value())
                     if self.tag() != 'as':
@@ -241,7 +246,8 @@
     if token.contents.strip() != 'endblocktrans':
         raise TemplateSyntaxError, "'blocktrans' doesn't allow other block 
tags (seen %r) inside it" % token.contents
 
-    return BlockTranslateNode(extra_context, singular, plural, countervar, 
counter)
+    return BlockTranslateNode(extra_context, singular, plural, countervar,
+            counter)
 
 register.tag('get_available_languages', do_get_available_languages)
 register.tag('get_current_language', do_get_current_language)

Modified: django/trunk/tests/regressiontests/templates/tests.py
===================================================================
--- django/trunk/tests/regressiontests/templates/tests.py       2007-11-17 
12:11:54 UTC (rev 6681)
+++ django/trunk/tests/regressiontests/templates/tests.py       2007-11-17 
12:12:18 UTC (rev 6682)
@@ -705,10 +705,10 @@
             'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, 
"xxxyyyxxx"),
 
             # simple translation of a variable
-            'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% 
endblocktrans %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"),
+            'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% 
endblocktrans %}', {'anton': '\xc3\x85'}, u"Å"),
 
             # simple translation of a variable and filter
-            'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta 
%}{{ berta }}{% endblocktrans %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"),
+            'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta 
%}{{ berta }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u'å'),
 
             # simple translation of a string with interpolation
             'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% 
endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"),
@@ -740,6 +740,11 @@
             'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 
'de', 'absent': ""}, 'Passwort'),
             'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'),
 
+            # Escaping inside blocktrans works as if it was directly in the
+            # template.
+            'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as 
berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α &amp; β'),
+            'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape 
as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α &amp; β'),
+
             ### HANDLING OF TEMPLATE_STRING_IF_INVALID 
###################################
 
             'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to