Django

Code

Changeset 5104

Show
Ignore:
Timestamp:
04/27/07 07:16:22 (2 years ago)
Author:
mtredinnick
Message:

Fixed #4164, #4171 -- Reworked some of the template lexer logic to ensure we
don't get caught out by a couple of corner cases.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/__init__.py

    r5091 r5104  
    194194    def tokenize(self): 
    195195        "Return a list of tokens from a given template_string" 
    196         # remove all empty strings, because the regex has a tendency to add them 
    197         bits = filter(None, tag_re.split(self.template_string)) 
    198         return map(self.create_token, bits) 
    199  
    200     def create_token(self,token_string): 
    201         "Convert the given token string into a new Token object and return it" 
    202         if token_string.startswith(VARIABLE_TAG_START): 
    203             token = Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip()) 
    204         elif token_string.startswith(BLOCK_TAG_START): 
    205             token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip()) 
    206         elif token_string.startswith(COMMENT_TAG_START): 
    207             token = Token(TOKEN_COMMENT, '') 
     196        in_tag = False 
     197        result = [] 
     198        for bit in tag_re.split(self.template_string): 
     199            if bit: 
     200                result.append(self.create_token(bit, in_tag)) 
     201            in_tag = not in_tag 
     202        return result 
     203 
     204    def create_token(self, token_string, in_tag=False): 
     205        """ 
     206        Convert the given token string into a new Token object and return it. 
     207        If tag is True, we are processing something that matched a tag, 
     208        otherwise it should be treated as a literal string. 
     209        """ 
     210        if in_tag: 
     211            if token_string.startswith(VARIABLE_TAG_START): 
     212                token = Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip()) 
     213            elif token_string.startswith(BLOCK_TAG_START): 
     214                token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip()) 
     215            elif token_string.startswith(COMMENT_TAG_START): 
     216                token = Token(TOKEN_COMMENT, '') 
    208217        else: 
    209218            token = Token(TOKEN_TEXT, token_string) 
     
    216225    def tokenize(self): 
    217226        "Return a list of tokens from a given template_string" 
    218         token_tups, upto = [], 0 
     227        result, upto = [], 0 
    219228        for match in tag_re.finditer(self.template_string): 
    220229            start, end = match.span() 
    221230            if start > upto: 
    222                 token_tups.append( (self.template_string[upto:start], (upto, start))
     231                result.append(self.create_token(self.template_string[upto:start], (upto, start), False)
    223232                upto = start 
    224             token_tups.append( (self.template_string[start:end], (start,end))
     233            result.append(self.create_token(self.template_string[start:end], (start, end), True)
    225234            upto = end 
    226235        last_bit = self.template_string[upto:] 
    227236        if last_bit: 
    228             token_tups.append( (last_bit, (upto, upto + len(last_bit)))
    229         return [self.create_token(tok, (self.origin, loc)) for tok, loc in token_tups] 
    230  
    231     def create_token(self, token_string, source): 
    232         token = super(DebugLexer, self).create_token(token_string
     237            result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False)
     238        return result 
     239 
     240    def create_token(self, token_string, source, in_tag): 
     241        token = super(DebugLexer, self).create_token(token_string, in_tag
    233242        token.source = source 
    234243        return token 
  • django/trunk/tests/regressiontests/templates/tests.py

    r5103 r5104  
    127127            # Fail silently when accessing a non-simple method 
    128128            'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ("","INVALID")), 
     129 
     130            # Don't get confused when parsing something that is almost, but not 
     131            # quite, a template tag. 
     132            'basic-syntax21': ("a {{ moo %} b", {}, "a {{ moo %} b"), 
     133            'basic-syntax22': ("{{ moo #}", {}, "{{ moo #}"), 
     134 
     135            # Will try to treat "moo #} {{ cow" as the variable. Not ideal, but 
     136            # costly to work around, so this triggers an error. 
     137            'basic-syntax23': ("{{ moo #} {{ cow }}", {"cow": "cow"}, template.TemplateSyntaxError), 
     138 
     139            # Embedded newlines make it not-a-tag. 
     140            'basic-syntax24': ("{{ moo\n }}", {}, "{{ moo\n }}"), 
    129141 
    130142            # List-index syntax allows a template to access a certain item of a subscriptable object.