Ticket #13567: ticket13567__r13864.diff

File ticket13567__r13864.diff, 4.8 KB (added by Łukasz Rekucki, 13 years ago)

Patch with docs and tests.

  • django/template/defaulttags.py

    commit da3621d572be50292d73ce3fb5b51b2eb3754a76
    Author: U-frozen\lreqc <lreqc@frozen.(none)>
    Date:   Sat Sep 25 03:16:12 2010 +0200
    
        First version of the patch.
    
    diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
    index 1b07413..687a744 100644
    a b class CsrfTokenNode(Node):  
    5353            return u''
    5454
    5555class CycleNode(Node):
    56     def __init__(self, cyclevars, variable_name=None):
     56    def __init__(self, cyclevars, variable_name=None, silent=False):
    5757        self.cyclevars = cyclevars
    5858        self.variable_name = variable_name
     59        self.silent = silent
    5960
    6061    def render(self, context):
    6162        if self not in context.render_context:
     63            # First time the node is rendered in template
    6264            context.render_context[self] = itertools_cycle(self.cyclevars)
     65            if self.silent:
     66                return ''
    6367        cycle_iter = context.render_context[self]
    6468        value = cycle_iter.next().resolve(context)
    6569        if self.variable_name:
    def cycle(parser, token):  
    482486    You can use any number of values, separated by spaces. Commas can also
    483487    be used to separate values; if a comma is used, the cycle values are
    484488    interpreted as literal strings.
     489
     490    The optional flag "silent" can be used to prevent the cycle declaration
     491    from returning any value::
     492
     493        {% cycle 'row1' 'row2' as rowcolors silent %}{# no value here #}
     494        {% for o in some_list %}
     495            <tr class="{% cycle rowcolors %}">{# first value will be "row1" #}
     496                ...
     497            </tr>
     498        {% endfor %}
     499
    485500    """
    486501
    487502    # Note: This returns the exact same node on each {% cycle name %} call;
    def cycle(parser, token):  
    513528            raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
    514529        return parser._namedCycleNodes[name]
    515530
    516     if len(args) > 4 and args[-2] == 'as':
     531    as_form = False
     532
     533    if len(args) > 4:
     534        # {% cycle ... as foo [silent] %} case.
     535        if args[-3] == "as":
     536            if args[-1] != "silent":
     537                raise TemplateSyntaxError("Only 'silent' flag is allowed after cycle's name, not '%s'." % args[-1])
     538            as_form = True
     539            silent = True
     540            args = args[:-1]
     541        elif args[-2] == "as":
     542            as_form = True
     543            silent = False
     544
     545    if as_form:
    517546        name = args[-1]
    518547        values = [parser.compile_filter(arg) for arg in args[1:-2]]
    519         node = CycleNode(values, name)
     548        node = CycleNode(values, name, silent=silent)
    520549        if not hasattr(parser, '_namedCycleNodes'):
    521550            parser._namedCycleNodes = {}
    522551        parser._namedCycleNodes[name] = node
  • docs/ref/templates/builtins.txt

    diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
    index 85c0b6d..f0c23c2 100644
    a b In this syntax, each value gets interpreted as a literal string, and there's no  
    140140way to specify variable values. Or literal commas. Or spaces. Did we mention
    141141you shouldn't use this syntax in any new projects?
    142142
     143.. versionadded:: 1.3
     144
     145By default, the cycle tag with "as" keyword will output the first value
     146of a cycle. This could be a problem if you want to use the value in a nested
     147loop or an included template. You can add a "silent" flag
     148and the end to prevent the output::
     149
     150    * Template::
     151
     152        {% for item in item_list %}
     153            {% cycle 'black' 'red' as item_class silent %}
     154            {% include "item.html" %}
     155        {% endfor %}
     156
     157    * The ``item.html`` template::
     158
     159        <div class="{{ item_class }}">...</div>
     160
     161This will produce a sequence of divs with first one having class "black".
     162
    143163.. templatetag:: debug
    144164
    145165debug
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index bbbcae3..c7c4b0f 100644
    a b class Templates(unittest.TestCase):  
    646646            'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'),
    647647            'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'),
    648648            'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'),
     649            'cycle17': ("{% cycle 'a' 'b' 'c' as abc silent %}{% cycle abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, "abca"),
     650            'cycle18': ("{% cycle 'a' 'b' 'c' as foo invalid_flag %}", {}, template.TemplateSyntaxError),
     651            'cycle19': ("{% cycle 'a' 'b' as silent %}{% cycle silent %}", {}, "ab"),
    649652
    650653            ### EXCEPTIONS ############################################################
    651654
Back to Top