- Author:
- wilfred
- Posted:
- January 16, 2013
- Language:
- Python
- Version:
- Not specified
- Score:
- 0 (after 0 ratings)
This tag is equivalent to {% cycle %} but resets when we exit the containing loop.
See Django ticket "Cycle tag should reset after it steps out of scope" https://code.djangoproject.com/ticket/5908
This code is a lightly modified version of Simon Litchfield's attachment on that ticket.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | from django import template
from django.template import Node, Variable
from django.template.base import TemplateSyntaxError
from itertools import cycle as itertools_cycle
"""{% safe_cycle %}
This tag is equivalent to {% cycle %} but resets when we exit the
containing loop.
See Django ticket "Cycle tag should reset after it steps out of scope"
https://code.djangoproject.com/ticket/5908
This code is a lightly modified version of Simon Litchfield's
attachment on that ticket.
"""
register = template.Library()
class SafeCycleNode(Node):
def __init__(self, cyclevars, variable_name=None):
self.cyclevars = cyclevars
self.cycle_iter = itertools_cycle(cyclevars)
self.variable_name = variable_name
def render(self, context):
if context.has_key('forloop'):
if not context.get(self):
context[self] = True
self.cycle_iter = itertools_cycle(self.cyclevars)
value = self.cycle_iter.next()
value = Variable(value).resolve(context)
if self.variable_name:
context[self.variable_name] = value
return value
@register.tag
def safe_cycle(parser, token):
"""
Cycles among the given strings each time this tag is encountered.
Within a loop, cycles among the given strings each time through
the loop::
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
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 rowcolors %}">...</tr>
<tr class="{% cycle rowcolors %}">...</tr>
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 returned from {% cycle name %} are the exact same object. This
# shouldn't cause problems (heh), but if it does, now you know.
#
# Ugly hack warning: this stuffs the named template dict into parser so
# that names are only unique within each template (as opposed to using
# a global variable, which would make cycle names have to be unique across
# *all* templates.
args = token.split_contents()
if len(args) < 2:
raise TemplateSyntaxError("'cycle' tag requires at least two arguments")
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(",")]
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 not name in parser._namedCycleNodes:
raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
return parser._namedCycleNodes[name]
if len(args) > 4 and args[-2] == 'as':
name = args[-1]
node = SafeCycleNode(args[1:-2], name)
if not hasattr(parser, '_namedCycleNodes'):
parser._namedCycleNodes = {}
parser._namedCycleNodes[name] = node
else:
node = SafeCycleNode(args[1:])
return node
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Please login first before commenting.