]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
clarify cycler.next() behavior 1085/head
authorDavid Lord <davidism@gmail.com>
Sun, 20 Oct 2019 23:42:14 +0000 (16:42 -0700)
committerDavid Lord <davidism@gmail.com>
Sun, 20 Oct 2019 23:42:14 +0000 (16:42 -0700)
docs/templates.rst
jinja2/utils.py

index b2ce444020f0f4516e8f6be84d32632dbd388974..5c1d92acd576395e474502f3601e61b1645b53cc 100644 (file)
@@ -1480,41 +1480,44 @@ The following functions are available in the global scope by default:
 
 .. 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=', ')
 
index a6f4dca0b817488189187f469dc1cec381119bc6..fb689dd7b3eb2dc33c428fbd7f99b49e66dac3dd 100644 (file)
@@ -566,27 +566,53 @@ def htmlsafe_json_dumps(obj, dumper=None, **kwargs):
     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