Django

Code

Changeset 6682

Show
Ignore:
Timestamp:
11/17/07 06:12:18 (1 year ago)
Author:
mtredinnick
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/templatetags/i18n.py

    r6565 r6682  
    11import re 
    22 
    3 from django.template import Node, Variable 
     3from django.template import Node, Variable, VariableNode 
    44from django.template import TemplateSyntaxError, TokenParser, Library 
    55from django.template import TOKEN_TEXT, TOKEN_VAR 
    66from django.utils import translation 
     7from django.utils.encoding import force_unicode 
    78 
    89register = Library() 
     
    4647 
    4748class BlockTranslateNode(Node): 
    48     def __init__(self, extra_context, singular, plural=None, countervar=None, counter=None): 
     49    def __init__(self, extra_context, singular, plural=None, countervar=None, 
     50            counter=None): 
    4951        self.extra_context = extra_context 
    5052        self.singular = singular 
     
    5557    def render_token_list(self, tokens): 
    5658        result = [] 
     59        vars = [] 
    5760        for token in tokens: 
    5861            if token.token_type == TOKEN_TEXT: 
    5962                result.append(token.contents) 
    6063            elif token.token_type == TOKEN_VAR: 
    61                 result.append('%%(%s)s' % token.contents) 
    62         return ''.join(result) 
     64                result.append(u'%%(%s)s' % token.contents) 
     65                vars.append(token.contents) 
     66        return ''.join(result), vars 
    6367 
    6468    def render(self, context): 
    6569        context.push() 
    66         for var,val in self.extra_context.items(): 
    67             context[var] = val.resolve(context) 
    68         singular = self.render_token_list(self.singular) 
     70        for var, val in self.extra_context.items(): 
     71            context[var] = val.render(context) 
     72        singular, vars = self.render_token_list(self.singular) 
    6973        if self.plural and self.countervar and self.counter: 
    7074            count = self.counter.resolve(context) 
    7175            context[self.countervar] = count 
    72             plural = self.render_token_list(self.plural) 
     76            plural = self.render_token_list(self.plural)[0] 
    7377            result = translation.ungettext(singular, plural, count) 
    7478        else: 
    7579            result = translation.ugettext(singular) 
    7680        # Escape all isolated '%' before substituting in the context. 
    77         result = re.sub('%(?!\()', '%%', result) % context 
     81        result = re.sub(u'%(?!\()', u'%%', result) 
     82        data = dict([(v, force_unicode(context[v])) for v in vars]) 
    7883        context.pop() 
    79         return result 
     84        return result % data 
    8085 
    8186def do_get_available_languages(parser, token): 
     
    199204    """ 
    200205    class BlockTranslateParser(TokenParser): 
    201  
    202206        def top(self): 
    203207            countervar = None 
     
    210214                    if self.tag() != 'as': 
    211215                        raise TemplateSyntaxError, "variable bindings in 'blocktrans' must be 'with value as variable'" 
    212                     extra_context[self.tag()] = parser.compile_filter(value) 
     216                    extra_context[self.tag()] = VariableNode( 
     217                            parser.compile_filter(value)) 
    213218                elif tag == 'count': 
    214219                    counter = parser.compile_filter(self.value()) 
     
    242247        raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents 
    243248 
    244     return BlockTranslateNode(extra_context, singular, plural, countervar, counter) 
     249    return BlockTranslateNode(extra_context, singular, plural, countervar, 
     250            counter) 
    245251 
    246252register.tag('get_available_languages', do_get_available_languages) 
  • django/trunk/tests/regressiontests/templates/tests.py

    r6680 r6682  
    706706 
    707707            # simple translation of a variable 
    708             'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"), 
     708            'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u"Å"), 
    709709 
    710710            # simple translation of a variable and filter 
    711             'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"), 
     711            'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u'å'), 
    712712 
    713713            # simple translation of a string with interpolation 
     
    740740            'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 'de', 'absent': ""}, 'Passwort'), 
    741741            'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'), 
     742 
     743            # Escaping inside blocktrans works as if it was directly in the 
     744            # template. 
     745            'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α &amp; β'), 
     746            'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α &amp; β'), 
    742747 
    743748            ### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################