Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
  • Loading branch information...
commit c260c533e1f1553548fc98f24820805af87f72bf 1 parent 32adde7
Russell Keith-Magee authored March 08, 2011
4  django/template/defaulttags.py
@@ -111,12 +111,12 @@ def render(self, context):
111 111
         if self not in context.render_context:
112 112
             # First time the node is rendered in template
113 113
             context.render_context[self] = itertools_cycle(self.cyclevars)
114  
-            if self.silent:
115  
-                return ''
116 114
         cycle_iter = context.render_context[self]
117 115
         value = cycle_iter.next().resolve(context)
118 116
         if self.variable_name:
119 117
             context[self.variable_name] = value
  118
+        if self.silent:
  119
+            return ''
120 120
         return value
121 121
 
122 122
 class DebugNode(Node):
51  docs/ref/templates/builtins.txt
@@ -102,11 +102,31 @@ outside of a loop. To do this, just give the ``{% cycle %}`` tag a name, using
102 102
 
103 103
     {% cycle 'row1' 'row2' as rowcolors %}
104 104
 
105  
-From then on, you can insert the current value of the cycle wherever you'd like
106  
-in your template::
107  
-
108  
-    <tr class="{% cycle rowcolors %}">...</tr>
109  
-    <tr class="{% cycle rowcolors %}">...</tr>
  105
+From then on, you can insert the current value of the cycle wherever
  106
+you'd like in your template by referencing the cycle name as a context
  107
+variable. If you want to move the cycle onto the next value, you use
  108
+the cycle tag again, using the name of the variable. So, the following
  109
+template::
  110
+
  111
+    <tr>
  112
+        <td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
  113
+        <td class="{{ rowcolors }}">...</td>
  114
+    </tr>
  115
+    <tr>
  116
+        <td class="{% cycle rowcolors %}">...</td>
  117
+        <td class="{{ rowcolors }}">...</td>
  118
+    </tr>
  119
+
  120
+would output::
  121
+
  122
+    <tr>
  123
+        <td class="row1">...</td>
  124
+        <td class="row1">...</td>
  125
+    </tr>
  126
+    <tr>
  127
+        <td class="row2">...</td>
  128
+        <td class="row2">...</td>
  129
+    </tr>
110 130
 
111 131
 You can use any number of values in a ``{% cycle %}`` tag, separated by spaces.
112 132
 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
144 164
 just declare the cycle, but not output the first value, you can add a
145 165
 ``silent`` keyword as the last keyword in the tag. For example::
146 166
 
147  
-    {% cycle 'row1' 'row2' as rowcolors silent %}
148 167
     {% for obj in some_list %}
149  
-        <tr class="{% cycle rowcolors %}">{{ obj }}</tr>
  168
+        {% cycle 'row1' 'row2' as rowcolors silent %}
  169
+        <tr class="{{ rowcolors }}">{% include "subtemplate.html " %}</tr>
150 170
     {% endfor %}
151 171
 
152 172
 This will output a list of ``<tr>`` elements with ``class``
153  
-alternating between ``row1`` and ``row2``. If the ``silent`` keyword
154  
-were to be omitted, ``row1`` would be emitted as normal text, outside
155  
-the list of ``<tr>`` elements, and the first ``<tr>`` would have a
156  
-class of ``row2``.
  173
+alternating between ``row1`` and ``row2``; the subtemplate will have
  174
+access to ``rowcolors`` in it's context that matches the class of the
  175
+``<tr>`` that encloses it. If the ``silent`` keyword were to be
  176
+omitted, ``row1`` would be emitted as normal text, outside the
  177
+``<tr>`` element.
  178
+
  179
+When the silent keyword is used on a cycle definition, the silence
  180
+automatically applies to all subsequent uses of the cycle tag. In,
  181
+the following template would output *nothing*, even though the second
  182
+call to ``{% cycle %}`` doesn't specify silent::
  183
+
  184
+    {% cycle 'row1' 'row2' as rowcolors silent %}
  185
+    {% cycle rowcolors %}
157 186
 
158 187
 .. templatetag:: debug
159 188
 
6  tests/regressiontests/templates/tests.py
@@ -735,11 +735,15 @@ def get_template_tests(self):
735 735
             'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'),
736 736
             'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'),
737 737
             'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'),
738  
-            'cycle17': ("{% cycle 'a' 'b' 'c' as abc silent %}{% cycle abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, "abca"),
  738
+            'cycle17': ("{% cycle 'a' 'b' 'c' as abc silent %}{% cycle abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, ""),
739 739
             'cycle18': ("{% cycle 'a' 'b' 'c' as foo invalid_flag %}", {}, template.TemplateSyntaxError),
740 740
             'cycle19': ("{% cycle 'a' 'b' as silent %}{% cycle silent %}", {}, "ab"),
741 741
             'cycle20': ("{% cycle one two as foo %} &amp; {% cycle foo %}", {'one' : 'A & B', 'two' : 'C & D'}, "A & B &amp; C & D"),
742 742
             'cycle21': ("{% filter force_escape %}{% cycle one two as foo %} & {% cycle foo %}{% endfilter %}", {'one' : 'A & B', 'two' : 'C & D'}, "A &amp; B &amp; C &amp; D"),
  743
+            'cycle22': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{{ x }}{% endfor %}", {'values': [1,2,3,4]}, "1234"),
  744
+            'cycle23': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{{ abc }}{{ x }}{% endfor %}", {'values': [1,2,3,4]}, "a1b2c3a4"),
  745
+            'included-cycle': ('{{ abc }}', {'abc': 'xxx'}, 'xxx'),
  746
+            'cycle24': ("{% for x in values %}{% cycle 'a' 'b' 'c' as abc silent %}{% include 'included-cycle' %}{% endfor %}", {'values': [1,2,3,4]}, "abca"),
743 747
 
744 748
             ### EXCEPTIONS ############################################################
745 749
 

0 notes on commit c260c53

Please sign in to comment.
Something went wrong with that request. Please try again.