Fixed #15570 -- Corrected a flaw in the design of the silent flag on {% cycle %}. Thanks to Brian Neal for the report, and to Andrew and Jannis for the design consult.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15773 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
32adde7fc9
commit
c260c533e1
|
@ -111,12 +111,12 @@ class CycleNode(Node):
|
||||||
if self not in context.render_context:
|
if self not in context.render_context:
|
||||||
# First time the node is rendered in template
|
# First time the node is rendered in template
|
||||||
context.render_context[self] = itertools_cycle(self.cyclevars)
|
context.render_context[self] = itertools_cycle(self.cyclevars)
|
||||||
if self.silent:
|
|
||||||
return ''
|
|
||||||
cycle_iter = context.render_context[self]
|
cycle_iter = context.render_context[self]
|
||||||
value = cycle_iter.next().resolve(context)
|
value = cycle_iter.next().resolve(context)
|
||||||
if self.variable_name:
|
if self.variable_name:
|
||||||
context[self.variable_name] = value
|
context[self.variable_name] = value
|
||||||
|
if self.silent:
|
||||||
|
return ''
|
||||||
return value
|
return value
|
||||||
|
|
||||||
class DebugNode(Node):
|
class DebugNode(Node):
|
||||||
|
|
|
@ -102,11 +102,31 @@ outside of a loop. To do this, just give the ``{% cycle %}`` tag a name, using
|
||||||
|
|
||||||
{% cycle 'row1' 'row2' as rowcolors %}
|
{% cycle 'row1' 'row2' as rowcolors %}
|
||||||
|
|
||||||
From then on, you can insert the current value of the cycle wherever you'd like
|
From then on, you can insert the current value of the cycle wherever
|
||||||
in your template::
|
you'd like in your template by referencing the cycle name as a context
|
||||||
|
variable. If you want to move the cycle onto the next value, you use
|
||||||
|
the cycle tag again, using the name of the variable. So, the following
|
||||||
|
template::
|
||||||
|
|
||||||
<tr class="{% cycle rowcolors %}">...</tr>
|
<tr>
|
||||||
<tr class="{% cycle rowcolors %}">...</tr>
|
<td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
|
||||||
|
<td class="{{ rowcolors }}">...</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="{% cycle rowcolors %}">...</td>
|
||||||
|
<td class="{{ rowcolors }}">...</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
would output::
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="row1">...</td>
|
||||||
|
<td class="row1">...</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="row2">...</td>
|
||||||
|
<td class="row2">...</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
You can use any number of values in a ``{% cycle %}`` tag, separated by spaces.
|
You can use any number of values in a ``{% cycle %}`` tag, separated by spaces.
|
||||||
Values enclosed in single (``'``) or double quotes (``"``) are treated as
|
Values enclosed in single (``'``) or double quotes (``"``) are treated as
|
||||||
|
@ -144,16 +164,25 @@ use the value in a nested loop or an included template. If you want to
|
||||||
just declare the cycle, but not output the first value, you can add a
|
just declare the cycle, but not output the first value, you can add a
|
||||||
``silent`` keyword as the last keyword in the tag. For example::
|
``silent`` keyword as the last keyword in the tag. For example::
|
||||||
|
|
||||||
{% cycle 'row1' 'row2' as rowcolors silent %}
|
|
||||||
{% for obj in some_list %}
|
{% for obj in some_list %}
|
||||||
<tr class="{% cycle rowcolors %}">{{ obj }}</tr>
|
{% cycle 'row1' 'row2' as rowcolors silent %}
|
||||||
|
<tr class="{{ rowcolors }}">{% include "subtemplate.html " %}</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
This will output a list of ``<tr>`` elements with ``class``
|
This will output a list of ``<tr>`` elements with ``class``
|
||||||
alternating between ``row1`` and ``row2``. If the ``silent`` keyword
|
alternating between ``row1`` and ``row2``; the subtemplate will have
|
||||||
were to be omitted, ``row1`` would be emitted as normal text, outside
|
access to ``rowcolors`` in it's context that matches the class of the
|
||||||
the list of ``<tr>`` elements, and the first ``<tr>`` would have a
|
``<tr>`` that encloses it. If the ``silent`` keyword were to be
|
||||||
class of ``row2``.
|
omitted, ``row1`` would be emitted as normal text, outside the
|
||||||
|
``<tr>`` element.
|
||||||
|
|
||||||
|
When the silent keyword is used on a cycle definition, the silence
|
||||||
|
automatically applies to all subsequent uses of the cycle tag. In,
|
||||||
|
the following template would output *nothing*, even though the second
|
||||||
|
call to ``{% cycle %}`` doesn't specify silent::
|
||||||
|
|
||||||
|
{% cycle 'row1' 'row2' as rowcolors silent %}
|
||||||
|
{% cycle rowcolors %}
|
||||||
|
|
||||||
.. templatetag:: debug
|
.. templatetag:: debug
|
||||||
|
|
||||||
|
|
|
@ -735,11 +735,15 @@ class Templates(unittest.TestCase):
|
||||||
'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'),
|
'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'),
|
||||||
'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'),
|
'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'),
|
||||||
'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'),
|
'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'),
|
||||||
'cycle17': ("{% cycle 'a' 'b' 'c' as abc silent %}{% cycle abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, "abca"),
|
'cycle17': ("{% cycle 'a' 'b' 'c' as abc silent %}{% cycle abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, ""),
|
||||||
'cycle18': ("{% cycle 'a' 'b' 'c' as foo invalid_flag %}", {}, template.TemplateSyntaxError),
|
'cycle18': ("{% cycle 'a' 'b' 'c' as foo invalid_flag %}", {}, template.TemplateSyntaxError),
|
||||||
'cycle19': ("{% cycle 'a' 'b' as silent %}{% cycle silent %}", {}, "ab"),
|
'cycle19': ("{% cycle 'a' 'b' as silent %}{% cycle silent %}", {}, "ab"),
|
||||||
'cycle20': ("{% cycle one two as foo %} & {% cycle foo %}", {'one' : 'A & B', 'two' : 'C & D'}, "A & B & C & D"),
|
'cycle20': ("{% cycle one two as foo %} & {% cycle foo %}", {'one' : 'A & B', 'two' : 'C & D'}, "A & B & C & D"),
|
||||||
'cycle21': ("{% filter force_escape %}{% cycle one two as foo %} & {% cycle foo %}{% endfilter %}", {'one' : 'A & B', 'two' : 'C & D'}, "A & B & C & D"),
|
'cycle21': ("{% filter force_escape %}{% cycle one two as foo %} & {% cycle foo %}{% endfilter %}", {'one' : 'A & B', 'two' : 'C & D'}, "A & B & C & D"),
|
||||||
|
'cycle22': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{{ x }}{% endfor %}", {'values': [1,2,3,4]}, "1234"),
|
||||||
|
'cycle23': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{{ abc }}{{ x }}{% endfor %}", {'values': [1,2,3,4]}, "a1b2c3a4"),
|
||||||
|
'included-cycle': ('{{ abc }}', {'abc': 'xxx'}, 'xxx'),
|
||||||
|
'cycle24': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{% include 'included-cycle' %}{% endfor %}", {'values': [1,2,3,4]}, "abca"),
|
||||||
|
|
||||||
### EXCEPTIONS ############################################################
|
### EXCEPTIONS ############################################################
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue