Ticket #208: 208.patch

File 208.patch, 7.6 KB (added by chris.mcavoy@…, 8 years ago)

Patch that changes behavior of cycle tag according to Adrian's description.

  • django/template/defaulttags.py

     
    22
    33from django.template import Node, NodeList, Template, Context, resolve_variable
    44from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
    5 from django.template import get_library, Library, InvalidTemplateLibrary
     5from django.template import get_library, Library, InvalidTemplateLibrary, resolve_variable
    66from django.conf import settings
    77import sys
    88
     
    2222    def render(self, context):
    2323        self.counter += 1
    2424        value = self.cyclevars[self.counter % self.cyclevars_len]
     25        value = resolve_variable(value, context)
    2526        if self.variable_name:
    2627            context[self.variable_name] = value
    2728        return value
     
    372373    the loop::
    373374
    374375        {% for o in some_list %}
    375             <tr class="{% cycle row1,row2 %}">
     376            <tr class="{% cycle 'row1' 'row2' %}">
    376377                ...
    377378            </tr>
    378379        {% endfor %}
     
    380381    Outside of a loop, give the values a unique name the first time you call
    381382    it, then use that name each sucessive time through::
    382383
    383             <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr>
     384            <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr>
    384385            <tr class="{% cycle rowcolors %}">...</tr>
    385386            <tr class="{% cycle rowcolors %}">...</tr>
    386387
    387     You can use any number of values, seperated by commas. Make sure not to
    388     put spaces between the values -- only commas.
     388    You can use any number of values, seperated by spaces.
    389389    """
    390390
    391391    # Note: This returns the exact same node on each {% cycle name %} call; that
    392     # is, the node object returned from {% cycle a,b,c as name %} and the one
     392    # is, the node object returned from {% cycle a b c as name %} and the one
    393393    # returned from {% cycle name %} are the exact same object.  This shouldn't
    394394    # cause problems (heh), but if it does, now you know.
    395395    #
     
    398398    # a global variable, which would make cycle names have to be unique across
    399399    # *all* templates.
    400400
    401     args = token.contents.split()
     401    args = token.split_contents()
     402   
    402403    if len(args) < 2:
    403         raise TemplateSyntaxError("'Cycle' statement requires at least two arguments")
     404        raise TemplateSyntaxError("Cycle' statement requires at least two arguments")
    404405
    405     elif len(args) == 2 and "," in args[1]:
    406         # {% cycle a,b,c %}
    407         cyclevars = [v for v in args[1].split(",") if v]    # split and kill blanks
    408         return CycleNode(cyclevars)
    409         # {% cycle name %}
    410 
    411     elif len(args) == 2:
     406    if len(args) == 2:
     407        # {% cycle foo %} case
    412408        name = args[1]
    413409        if not hasattr(parser, '_namedCycleNodes'):
    414410            raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name)
     
    416412            raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
    417413        return parser._namedCycleNodes[name]
    418414
    419     elif len(args) == 4:
    420         # {% cycle a,b,c as name %}
    421         if args[2] != 'as':
    422             raise TemplateSyntaxError("Second 'cycle' argument must be 'as'")
    423         cyclevars = [v for v in args[1].split(",") if v]    # split and kill blanks
    424         name = args[3]
    425         node = CycleNode(cyclevars, name)
    426 
    427         if not hasattr(parser, '_namedCycleNodes'):
    428             parser._namedCycleNodes = {}
    429 
    430         parser._namedCycleNodes[name] = node
     415    if len(args) > 2 and args[-2]:
     416        if args[-2] == 'as':
     417            # {% cycle 'value 1' 'value 2' 'value 3' as foo %} case
     418            name = args[-1]
     419            cyclevars = args[1:-2]
     420            node = CycleNode(cyclevars, name)
     421            if not hasattr(parser, '_namedCycleNodes'):
     422                parser._namedCycleNodes = {}
     423            parser._namedCycleNodes[name] = node
     424        else:
     425            # {% cycle 'value 1' 'value 2' 'value 3' %} case
     426            cyclevars = args[1:]
     427            node = CycleNode(cyclevars)
     428       
    431429        return node
    432430
    433     else:
    434         raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args)
     431    # none of the cases were met
     432    raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args)
     433   
    435434cycle = register.tag(cycle)
    436435
    437436def debug(parser, token):
  • tests/regressiontests/templates/tests.py

     
    233233
    234234            ### CYCLE TAG #############################################################
    235235            'cycle01': ('{% cycle a %}', {}, template.TemplateSyntaxError),
    236             'cycle02': ('{% cycle a,b,c as abc %}{% cycle abc %}', {}, 'ab'),
    237             'cycle03': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}', {}, 'abc'),
    238             'cycle04': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}', {}, 'abca'),
    239             'cycle05': ('{% cycle %}', {}, template.TemplateSyntaxError),
    240             'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError),
    241             'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError),
    242             'cycle08': ('{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}', {}, 'abbbcc'),
     236            'cycle02': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}", {}, 'ab'),
     237            'cycle03': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}", {}, 'abc'),
     238            'cycle04': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, 'abca'),
     239            'cycle05': ("{% cycle %}", {}, template.TemplateSyntaxError),
     240            'cycle06': ("{% cycle a %}", {}, template.TemplateSyntaxError),
     241            'cycle07': ("{% cycle 'a' 'b' 'c' as foo %}{% cycle bar %}", {}, template.TemplateSyntaxError),
     242            'cycle08': ("{% cycle 'a' 'b' 'c' as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}",
     243                        {}, 'abbbcc'),
     244            'cycle09': ("{% cycle 'chris 1' 'camri is cute' 'cotton' as foo %}{% cycle foo %}", {}, 'chris 1camri is cute'),
     245            'cycle10': ("{% for i in test %}{% cycle 'row1' 'row2' %}{% endfor %}", {'test':[1,2]}, 'row1row2'),
     246            'cycle11': ("{% cycle one two as foo %}{% cycle foo %}", {'one':'1','two':'2'}, '12'),
    243247
    244248            ### EXCEPTIONS ############################################################
    245249
  • docs/templates.txt

     
    364364Within a loop, cycles among the given strings each time through the loop::
    365365
    366366    {% for o in some_list %}
    367         <tr class="{% cycle row1,row2 %}">
     367        <tr class="{% cycle 'row1' 'row2' %}">
    368368            ...
    369369        </tr>
    370370    {% endfor %}
     
    372372Outside of a loop, give the values a unique name the first time you call it,
    373373then use that name each successive time through::
    374374
    375         <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr>
     375        <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr>
    376376        <tr class="{% cycle rowcolors %}">...</tr>
    377377        <tr class="{% cycle rowcolors %}">...</tr>
    378378
    379 You can use any number of values, separated by commas. Make sure not to put
    380 spaces between the values -- only commas.
     379You can use any number of values,  separated by spaces.
    381380
    382381debug
    383382~~~~~
Back to Top