Django

Code

Ticket #208: 208.4.patch

File 208.4.patch, 6.7 kB (added by SmileyChris, 1 year ago)

new patch, reviewed and refactored

  • django/template/defaulttags.py

    old new  
    3030    def render(self, context): 
    3131        self.counter += 1 
    3232        value = self.cyclevars[self.counter % self.cyclevars_len] 
     33        value = resolve_variable(value, context) 
    3334        if self.variable_name: 
    3435            context[self.variable_name] = value 
    3536        return value 
     
    403404    the loop:: 
    404405 
    405406        {% for o in some_list %} 
    406             <tr class="{% cycle row1,row2 %}"> 
     407            <tr class="{% cycle 'row1' 'row2' %}"> 
    407408                ... 
    408409            </tr> 
    409410        {% endfor %} 
     
    411412    Outside of a loop, give the values a unique name the first time you call 
    412413    it, then use that name each sucessive time through:: 
    413414 
    414             <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr> 
     415            <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr> 
    415416            <tr class="{% cycle rowcolors %}">...</tr> 
    416417            <tr class="{% cycle rowcolors %}">...</tr> 
    417418 
    418     You can use any number of values, seperated by commas. Make sure not to 
    419     put spaces between the values -- only commas. 
     419    You can use any number of values, seperated by spaces. 
    420420    """ 
    421421 
    422422    # Note: This returns the exact same node on each {% cycle name %} call; that 
    423     # is, the node object returned from {% cycle a,b,c as name %} and the one 
     423    # is, the node object returned from {% cycle a b c as name %} and the one 
    424424    # returned from {% cycle name %} are the exact same object.  This shouldn't 
    425425    # cause problems (heh), but if it does, now you know. 
    426426    # 
     
    429429    # a global variable, which would make cycle names have to be unique across 
    430430    # *all* templates. 
    431431 
    432     args = token.contents.split() 
     432    args = token.split_contents() 
     433 
    433434    if len(args) < 2: 
    434         raise TemplateSyntaxError("'Cycle' statement requires at least two arguments") 
     435       raise TemplateSyntaxError("'cycle' tag requires at least two arguments") 
    435436 
    436     elif len(args) == 2 and "," in args[1]: 
    437         # {% cycle a,b,c %} 
    438         cyclevars = [v for v in args[1].split(",") if v]    # split and kill blanks 
    439         return CycleNode(cyclevars) 
    440         # {% cycle name %} 
     437    if ',' in args[1]: 
     438        # Backwards compatibility: {% cycle a,b %} or {% cycle a,b as foo %} 
     439        # case. 
     440        args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] 
    441441 
    442     elif len(args) == 2: 
     442    if len(args) == 2: 
     443        # {% cycle foo %} case 
    443444        name = args[1] 
    444445        if not hasattr(parser, '_namedCycleNodes'): 
    445446            raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name) 
    446         if name not in parser._namedCycleNodes: 
     447        if not name in parser._namedCycleNodes: 
    447448            raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) 
    448449        return parser._namedCycleNodes[name] 
    449450 
    450     elif len(args) == 4: 
    451         # {% cycle a,b,c as name %} 
    452         if args[2] != 'as': 
    453             raise TemplateSyntaxError("Second 'cycle' argument must be 'as'") 
    454         cyclevars = [v for v in args[1].split(",") if v]    # split and kill blanks 
    455         name = args[3] 
    456         node = CycleNode(cyclevars, name) 
    457  
     451    if len(args) > 4 and args[-2] == 'as': 
     452        name = args[-1] 
     453        node = CycleNode(args[1:-2], name) 
    458454        if not hasattr(parser, '_namedCycleNodes'): 
    459455            parser._namedCycleNodes = {} 
    460  
    461456        parser._namedCycleNodes[name] = node 
    462         return node 
    463  
    464457    else: 
    465         raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args) 
     458        node = CycleNode(args[1:]) 
     459    return node 
    466460cycle = register.tag(cycle) 
    467461 
    468462def debug(parser, token): 
  • docs/templates.txt

    old new  
    366366cycle 
    367367~~~~~ 
    368368 
    369 Cycle among the given strings each time this tag is encountered. 
     369Cycle among the given strings or variables each time this tag is encountered. 
    370370 
    371 Within a loop, cycles among the given strings each time through the loop:: 
     371Within a loop, cycles among the given strings/variables each time through the 
     372loop:: 
    372373 
    373374    {% for o in some_list %} 
    374         <tr class="{% cycle row1,row2 %}"> 
     375        <tr class="{% cycle 'row1' 'row2' rowvar %}"> 
    375376            ... 
    376377        </tr> 
    377378    {% endfor %} 
    378  
     379  
    379380Outside of a loop, give the values a unique name the first time you call it, 
    380381then use that name each successive time through:: 
    381382 
    382         <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr> 
     383        <tr class="{% cycle 'row1' 'row2' rowvar as rowcolors %}">...</tr> 
    383384        <tr class="{% cycle rowcolors %}">...</tr> 
    384385        <tr class="{% cycle rowcolors %}">...</tr> 
    385386 
    386 You can use any number of values, separated by commas. Make sure not to put 
    387 spaces between the values -- only commas. 
     387You can use any number of values, separated by spaces. Values enclosed in  
     388single (') or double quotes (") are treated as string literals, while values  
     389without quotes are assumed to refer to context variables.  
    388390 
     391The depreciated comma-separated syntax (`{% cycle row1,row2 %}`) is still 
     392supported. 
     393 
    389394debug 
    390395~~~~~ 
    391396 
  • tests/regressiontests/templates/tests.py

    old new  
    306306            'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError), 
    307307            'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError), 
    308308            'cycle08': ('{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}', {}, 'abbbcc'), 
     309            'cycle09': ("{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), 
     310            # New format: 
     311            'cycle10': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}", {}, 'ab'), 
     312            'cycle11': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}", {}, 'abc'), 
     313            'cycle12': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, 'abca'), 
     314            'cycle13': ("{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), 
     315            'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'), 
     316            'cycle13': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'), 
    309317 
    310318            ### EXCEPTIONS ############################################################ 
    311319