.. class:: cycler(\*items)
- The cycler allows you to cycle among values similar to how `loop.cycle`
- works. Unlike `loop.cycle`, you can use this cycler outside of
- loops or over multiple loops.
+ Cycle through values by yielding them one at a time, then restarting
+ once the end is reached.
- This can be very useful if you want to show a list of folders and
- files with the folders on top but both in the same list with alternating
- row colors.
+ Similar to ``loop.cycle``, but can be used outside loops or across
+ multiple loops. For example, render a list of folders and files in a
+ list, alternating giving them "odd" and "even" classes.
- The following example shows how `cycler` can be used::
+ .. code-block:: html+jinja
- {% set row_class = cycler('odd', 'even') %}
+ {% set row_class = cycler("odd", "even") %}
<ul class="browser">
{% for folder in folders %}
- <li class="folder {{ row_class.next() }}">{{ folder|e }}</li>
+ <li class="folder {{ row_class.next() }}">{{ folder }}
{% endfor %}
- {% for filename in files %}
- <li class="file {{ row_class.next() }}">{{ filename|e }}</li>
+ {% for file in files %}
+ <li class="file {{ row_class.next() }}">{{ file }}
{% endfor %}
</ul>
- A cycler has the following attributes and methods:
+ :param items: Each positional argument will be yielded in the order
+ given for each cycle.
- .. method:: reset()
+ .. versionadded:: 2.1
- Resets the cycle to the first item.
+ .. method:: current
+ :property:
- .. method:: next()
+ Return the current item. Equivalent to the item that will be
+ returned next time :meth:`next` is called.
- Goes one item ahead and returns the then-current item.
+ .. method:: next()
- .. attribute:: current
+ Return the current item, then advance :attr:`current` to the
+ next item.
- Returns the current item.
+ .. method:: reset()
- .. versionadded:: 2.1
+ Resets the current item to the first item.
.. class:: joiner(sep=', ')
return Markup(rv)
-@implements_iterator
class Cycler(object):
- """A cycle helper for templates."""
+ """Cycle through values by yield them one at a time, then restarting
+ once the end is reached. Available as ``cycler`` in templates.
+
+ Similar to ``loop.cycle``, but can be used outside loops or across
+ multiple loops. For example, render a list of folders and files in a
+ list, alternating giving them "odd" and "even" classes.
+
+ .. code-block:: html+jinja
+
+ {% set row_class = cycler("odd", "even") %}
+ <ul class="browser">
+ {% for folder in folders %}
+ <li class="folder {{ row_class.next() }}">{{ folder }}
+ {% endfor %}
+ {% for file in files %}
+ <li class="file {{ row_class.next() }}">{{ file }}
+ {% endfor %}
+ </ul>
+
+ :param items: Each positional argument will be yielded in the order
+ given for each cycle.
+
+ .. versionadded:: 2.1
+ """
def __init__(self, *items):
if not items:
raise RuntimeError('at least one item has to be provided')
self.items = items
- self.reset()
+ self.pos = 0
def reset(self):
- """Resets the cycle."""
+ """Resets the current item to the first item."""
self.pos = 0
@property
def current(self):
- """Returns the current item."""
+ """Return the current item. Equivalent to the item that will be
+ returned next time :meth:`next` is called.
+ """
return self.items[self.pos]
def next(self):
- """Goes one item ahead and returns it."""
+ """Return the current item, then advance :attr:`current` to the
+ next item.
+ """
rv = self.current
self.pos = (self.pos + 1) % len(self.items)
return rv