summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2007-09-14 02:49:21 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2007-09-14 02:49:21 +0000
commit09145d2e5f1445d59d0c121394b78ec5ed196056 (patch)
treefffad80fef39a29cd64a42036bb0db0e9fd5a1c1
parenta2ce7669d902cf32eeac9307b804b78ed4150fe5 (diff)
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.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6153 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/admin/templates/admin/change_list_results.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/calendar_day.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/calendar_homepage.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/calendar_main.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/calendar_month.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/calendar_year.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/choice_detail.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/choice_list.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/fieldchoice_list.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/homepage.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/model_detail.html2
-rw-r--r--django/contrib/databrowse/templates/databrowse/object_detail.html4
-rw-r--r--django/template/defaulttags.py48
-rw-r--r--docs/templates.txt25
-rw-r--r--tests/regressiontests/templates/tests.py8
17 files changed, 63 insertions, 48 deletions
diff --git a/django/contrib/admin/templates/admin/change_list_results.html b/django/contrib/admin/templates/admin/change_list_results.html
index 3f755783dc..381dcb5d5d 100644
--- a/django/contrib/admin/templates/admin/change_list_results.html
+++ b/django/contrib/admin/templates/admin/change_list_results.html
@@ -10,7 +10,7 @@
</thead>
<tbody>
{% for result in results %}
-<tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr>
+<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
{% endfor %}
</tbody>
</table>
diff --git a/django/contrib/databrowse/templates/databrowse/calendar_day.html b/django/contrib/databrowse/templates/databrowse/calendar_day.html
index b0f57e1eae..bbb62cc814 100644
--- a/django/contrib/databrowse/templates/databrowse/calendar_day.html
+++ b/django/contrib/databrowse/templates/databrowse/calendar_day.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/calendar_homepage.html b/django/contrib/databrowse/templates/databrowse/calendar_homepage.html
index daf45dfdeb..85eb8af9eb 100644
--- a/django/contrib/databrowse/templates/databrowse/calendar_homepage.html
+++ b/django/contrib/databrowse/templates/databrowse/calendar_homepage.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
-<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/calendar_main.html b/django/contrib/databrowse/templates/databrowse/calendar_main.html
index 18ee5bdc8b..b22a44d321 100644
--- a/django/contrib/databrowse/templates/databrowse/calendar_main.html
+++ b/django/contrib/databrowse/templates/databrowse/calendar_main.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for year in date_list %}
-<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/calendar_month.html b/django/contrib/databrowse/templates/databrowse/calendar_month.html
index 67506f452f..70b7deb75a 100644
--- a/django/contrib/databrowse/templates/databrowse/calendar_month.html
+++ b/django/contrib/databrowse/templates/databrowse/calendar_month.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/calendar_year.html b/django/contrib/databrowse/templates/databrowse/calendar_year.html
index 729c2ddf3b..a6e6f53ba3 100644
--- a/django/contrib/databrowse/templates/databrowse/calendar_year.html
+++ b/django/contrib/databrowse/templates/databrowse/calendar_year.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for month in date_list %}
-<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/choice_detail.html b/django/contrib/databrowse/templates/databrowse/choice_detail.html
index e6add55021..6cb73e73ec 100644
--- a/django/contrib/databrowse/templates/databrowse/choice_detail.html
+++ b/django/contrib/databrowse/templates/databrowse/choice_detail.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/choice_list.html b/django/contrib/databrowse/templates/databrowse/choice_list.html
index 07a1319459..95cd88b0bf 100644
--- a/django/contrib/databrowse/templates/databrowse/choice_list.html
+++ b/django/contrib/databrowse/templates/databrowse/choice_list.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for choice in field.choices %}
-<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html b/django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html
index d1c8b877cb..7801f3f631 100644
--- a/django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html
+++ b/django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html b/django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html
index 8760bd4ad1..3259824061 100644
--- a/django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html
+++ b/django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
-<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html b/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
index 9f41213a6f..71b906d3e7 100644
--- a/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
+++ b/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/homepage.html b/django/contrib/databrowse/templates/databrowse/homepage.html
index 104a804253..718e577416 100644
--- a/django/contrib/databrowse/templates/databrowse/homepage.html
+++ b/django/contrib/databrowse/templates/databrowse/homepage.html
@@ -7,7 +7,7 @@
{% block content %}
{% for model in model_list %}
- <div class="modelgroup {% cycle even,odd %}">
+ <div class="modelgroup {% cycle 'even' 'odd' %}">
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
<p>
{% for object in model.sample_objects %}
diff --git a/django/contrib/databrowse/templates/databrowse/model_detail.html b/django/contrib/databrowse/templates/databrowse/model_detail.html
index 2084b18ca7..b66bc093dd 100644
--- a/django/contrib/databrowse/templates/databrowse/model_detail.html
+++ b/django/contrib/databrowse/templates/databrowse/model_detail.html
@@ -12,7 +12,7 @@
<ul class="objectlist">
{% for object in model.objects %}
- <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+ <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
diff --git a/django/contrib/databrowse/templates/databrowse/object_detail.html b/django/contrib/databrowse/templates/databrowse/object_detail.html
index e9977743fd..7c1bd3e16d 100644
--- a/django/contrib/databrowse/templates/databrowse/object_detail.html
+++ b/django/contrib/databrowse/templates/databrowse/object_detail.html
@@ -10,7 +10,7 @@
<table class="objectinfo">
{% for field in object.fields %}
-<tr class="{% cycle odd,even %}">
+<tr class="{% cycle 'odd' 'even' %}">
<th>{{ field.field.verbose_name|capfirst }}</th>
<td>
{% if field.urls %}
@@ -29,7 +29,7 @@
{% if related_object.object_list %}
<ul class="objectlist">
{% for object in related_object.object_list %}
- <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+ <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
{% else %}
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 11cd04653f..e41ca717e7 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -30,6 +30,7 @@ class CycleNode(Node):
def render(self, context):
self.counter += 1
value = self.cyclevars[self.counter % self.cyclevars_len]
+ value = resolve_variable(value, context)
if self.variable_name:
context[self.variable_name] = value
return value
@@ -403,7 +404,7 @@ def cycle(parser, token):
the loop::
{% for o in some_list %}
- <tr class="{% cycle row1,row2 %}">
+ <tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
@@ -411,16 +412,17 @@ def cycle(parser, token):
Outside of a loop, give the values a unique name the first time you call
it, then use that name each sucessive time through::
- <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr>
+ <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr>
<tr class="{% cycle rowcolors %}">...</tr>
<tr class="{% cycle rowcolors %}">...</tr>
- You can use any number of values, seperated by commas. Make sure not to
- put spaces between the values -- only commas.
+ You can use any number of values, seperated by spaces. Commas can also
+ be used to separate values; if a comma is used, the cycle values are
+ interpreted as literal strings.
"""
# Note: This returns the exact same node on each {% cycle name %} call; that
- # is, the node object returned from {% cycle a,b,c as name %} and the one
+ # is, the node object returned from {% cycle a b c as name %} and the one
# returned from {% cycle name %} are the exact same object. This shouldn't
# cause problems (heh), but if it does, now you know.
#
@@ -429,40 +431,34 @@ def cycle(parser, token):
# a global variable, which would make cycle names have to be unique across
# *all* templates.
- args = token.contents.split()
+ args = token.split_contents()
+
if len(args) < 2:
- raise TemplateSyntaxError("'Cycle' statement requires at least two arguments")
+ raise TemplateSyntaxError("'cycle' tag requires at least two arguments")
- elif len(args) == 2 and "," in args[1]:
- # {% cycle a,b,c %}
- cyclevars = [v for v in args[1].split(",") if v] # split and kill blanks
- return CycleNode(cyclevars)
- # {% cycle name %}
+ if ',' in args[1]:
+ # Backwards compatibility: {% cycle a,b %} or {% cycle a,b as foo %}
+ # case.
+ args[1:2] = ['"%s"' % arg for arg in args[1].split(",")]
- elif len(args) == 2:
+ if len(args) == 2:
+ # {% cycle foo %} case
name = args[1]
if not hasattr(parser, '_namedCycleNodes'):
raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name)
- if name not in parser._namedCycleNodes:
+ if not name in parser._namedCycleNodes:
raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
return parser._namedCycleNodes[name]
- elif len(args) == 4:
- # {% cycle a,b,c as name %}
- if args[2] != 'as':
- raise TemplateSyntaxError("Second 'cycle' argument must be 'as'")
- cyclevars = [v for v in args[1].split(",") if v] # split and kill blanks
- name = args[3]
- node = CycleNode(cyclevars, name)
-
+ if len(args) > 4 and args[-2] == 'as':
+ name = args[-1]
+ node = CycleNode(args[1:-2], name)
if not hasattr(parser, '_namedCycleNodes'):
parser._namedCycleNodes = {}
-
parser._namedCycleNodes[name] = node
- return node
-
else:
- raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args)
+ node = CycleNode(args[1:])
+ return node
cycle = register.tag(cycle)
def debug(parser, token):
diff --git a/docs/templates.txt b/docs/templates.txt
index 9f2bec1c8b..ff67579b87 100644
--- a/docs/templates.txt
+++ b/docs/templates.txt
@@ -366,25 +366,36 @@ Ignore everything between ``{% comment %}`` and ``{% endcomment %}``
cycle
~~~~~
-Cycle among the given strings each time this tag is encountered.
+**Changed in Django development version**
+Cycle among the given strings or variables each time this tag is encountered.
-Within a loop, cycles among the given strings each time through the loop::
+Within a loop, cycles among the given strings/variables each time through the
+loop::
{% for o in some_list %}
- <tr class="{% cycle row1,row2 %}">
+ <tr class="{% cycle 'row1' 'row2' rowvar %}">
...
</tr>
{% endfor %}
-
+
Outside of a loop, give the values a unique name the first time you call it,
then use that name each successive time through::
- <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr>
+ <tr class="{% cycle 'row1' 'row2' rowvar as rowcolors %}">...</tr>
<tr class="{% cycle rowcolors %}">...</tr>
<tr class="{% cycle rowcolors %}">...</tr>
-You can use any number of values, separated by commas. Make sure not to put
-spaces between the values -- only commas.
+You can use any number of values, separated by spaces. Values enclosed in
+single (') or double quotes (") are treated as string literals, while values
+without quotes are assumed to refer to context variables.
+
+You can also separate values with commas::
+
+ {% cycle row1,row2,row3 %}
+
+In this syntax, each value will be interpreted as literal text. The
+comma-based syntax exists for backwards-compatibility, and should not be
+used for new projects.
debug
~~~~~
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 0f7ac2f352..11dd092156 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -306,6 +306,14 @@ class Templates(unittest.TestCase):
'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError),
'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError),
'cycle08': ('{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}', {}, 'abbbcc'),
+ 'cycle09': ("{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'),
+ # New format:
+ 'cycle10': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}", {}, 'ab'),
+ 'cycle11': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}", {}, 'abc'),
+ 'cycle12': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, 'abca'),
+ 'cycle13': ("{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'),
+ 'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'),
+ 'cycle13': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'),
### EXCEPTIONS ############################################################