Django

Code

Changeset 6153

Show
Ignore:
Timestamp:
09/13/07 21:49:21 (8 months ago)
Author:
russellm
Message:

Fixed #208 -- Modernized the syntax of the cycle tag to allow for spaces and variables in cycle values. Thanks to SmileyChris? and Chris McAvoy? for their work on this.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/admin/templates/admin/change_list_results.html

    r1791 r6153  
    1111<tbody> 
    1212{% for result in results %} 
    13 <tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr> 
     13<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr> 
    1414{% endfor %} 
    1515</tbody> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/calendar_day.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for object in object_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/calendar_homepage.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for field in field_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/calendar_main.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for year in date_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/calendar_month.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for object in object_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/calendar_year.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for month in date_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/choice_detail.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for object in object_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/choice_list.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for choice in field.choices %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for object in object_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for field in field_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html

    r5947 r6153  
    1111<ul class="objectlist"> 
    1212{% for object in object_list %} 
    13 <li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li> 
     13<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li> 
    1414{% endfor %} 
    1515</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/homepage.html

    r5947 r6153  
    88 
    99{% for model in model_list %} 
    10   <div class="modelgroup {% cycle even,odd %}"> 
     10  <div class="modelgroup {% cycle 'even' 'odd' %}"> 
    1111          <h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2> 
    1212                <p> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/model_detail.html

    r5947 r6153  
    1313<ul class="objectlist"> 
    1414{% for object in model.objects %} 
    15     <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     15    <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    1616{% endfor %} 
    1717</ul> 
  • django/trunk/django/contrib/databrowse/templates/databrowse/object_detail.html

    r5947 r6153  
    1111<table class="objectinfo"> 
    1212{% for field in object.fields %} 
    13 <tr class="{% cycle odd,even %}"> 
     13<tr class="{% cycle 'odd' 'even' %}"> 
    1414<th>{{ field.field.verbose_name|capfirst }}</th> 
    1515<td> 
     
    3030  <ul class="objectlist"> 
    3131    {% for object in related_object.object_list %} 
    32     <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
     32    <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 
    3333    {% endfor %} 
    3434  </ul> 
  • django/trunk/django/template/defaulttags.py

    r5927 r6153  
    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 
     
    404405 
    405406        {% for o in some_list %} 
    406             <tr class="{% cycle row1,row2 %}"> 
     407            <tr class="{% cycle 'row1' 'row2' %}"> 
    407408                ... 
    408409            </tr> 
     
    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. Commas can also 
     420    be used to separate values; if a comma is used, the cycle values are  
     421    interpreted as literal strings. 
    420422    """ 
    421423 
    422424    # 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 
     425    # is, the node object returned from {% cycle a b c as name %} and the one 
    424426    # returned from {% cycle name %} are the exact same object.  This shouldn't 
    425427    # cause problems (heh), but if it does, now you know. 
     
    430432    # *all* templates. 
    431433 
    432     args = token.contents.split() 
     434    args = token.split_contents() 
     435 
    433436    if len(args) < 2: 
    434         raise TemplateSyntaxError("'Cycle' statement requires at least two arguments") 
    435  
    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 %} 
    441  
    442     elif len(args) == 2: 
     437        raise TemplateSyntaxError("'cycle' tag requires at least two arguments") 
     438 
     439    if ',' in args[1]: 
     440        # Backwards compatibility: {% cycle a,b %} or {% cycle a,b as foo %} 
     441        # case. 
     442        args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] 
     443 
     444    if len(args) == 2: 
     445        # {% cycle foo %} case 
    443446        name = args[1] 
    444447        if not hasattr(parser, '_namedCycleNodes'): 
    445448            raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name) 
    446         if name not in parser._namedCycleNodes: 
     449        if not name in parser._namedCycleNodes: 
    447450            raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) 
    448451        return parser._namedCycleNodes[name] 
    449452 
    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  
     453    if len(args) > 4 and args[-2] == 'as': 
     454        name = args[-1] 
     455        node = CycleNode(args[1:-2], name) 
    458456        if not hasattr(parser, '_namedCycleNodes'): 
    459457            parser._namedCycleNodes = {} 
    460  
    461458        parser._namedCycleNodes[name] = node 
    462         return node 
    463  
    464459    else: 
    465         raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args) 
     460        node = CycleNode(args[1:]) 
     461    return node 
    466462cycle = register.tag(cycle) 
    467463 
  • django/trunk/docs/templates.txt

    r6070 r6153  
    367367~~~~~ 
    368368 
    369 Cycle among the given strings each time this tag is encountered. 
    370  
    371 Within a loop, cycles among the given strings each time through the loop:: 
     369**Changed in Django development version** 
     370Cycle among the given strings or variables each time this tag is encountered. 
     371 
     372Within a loop, cycles among the given strings/variables each time through the 
     373loop:: 
    372374 
    373375    {% for o in some_list %} 
    374         <tr class="{% cycle row1,row2 %}"> 
     376        <tr class="{% cycle 'row1' 'row2' rowvar %}"> 
    375377            ... 
    376378        </tr> 
    377379    {% endfor %} 
    378  
     380  
    379381Outside of a loop, give the values a unique name the first time you call it, 
    380382then use that name each successive time through:: 
    381383 
    382         <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr> 
     384        <tr class="{% cycle 'row1' 'row2' rowvar as rowcolors %}">...</tr> 
    383385        <tr class="{% cycle rowcolors %}">...</tr> 
    384386        <tr class="{% cycle rowcolors %}">...</tr> 
    385387 
    386 You can use any number of values, separated by commas. Make sure not to put 
    387 spaces between the values -- only commas. 
     388You can use any number of values, separated by spaces. Values enclosed in  
     389single (') or double quotes (") are treated as string literals, while values  
     390without quotes are assumed to refer to context variables.  
     391 
     392You can also separate values with commas:: 
     393 
     394    {% cycle row1,row2,row3 %} 
     395     
     396In this syntax, each value will be interpreted as literal text. The  
     397comma-based syntax exists for backwards-compatibility, and should not be  
     398used for new projects. 
    388399 
    389400debug 
  • django/trunk/tests/regressiontests/templates/tests.py

    r5876 r6153  
    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 ############################################################