Ticket #3481: for_else.diff

File for_else.diff, 4.2 KB (added by rodolfo.3@…, 8 years ago)

This patch allow a tag "else" in a "for" loop.

  • django/template/defaulttags.py

     
    6969        return u''
    7070
    7171class ForNode(Node):
    72     def __init__(self, loopvars, sequence, reversed, nodelist_loop):
     72    def __init__(self, loopvars, sequence, reversed, nodelist_loop, nodelist_loop_empty):
    7373        self.loopvars, self.sequence = loopvars, sequence
    7474        self.reversed = reversed
    7575        self.nodelist_loop = nodelist_loop
     76        self.nodelist_loop_empty = nodelist_loop_empty
    7677
    7778    def __repr__(self):
    7879        if self.reversed:
     
    109110        if not hasattr(values, '__len__'):
    110111            values = list(values)
    111112        len_values = len(values)
    112         if self.reversed:
    113             values = reversed(values)
    114         unpack = len(self.loopvars) > 1
    115         for i, item in enumerate(values):
    116             context['forloop'] = {
    117                 # shortcuts for current loop iteration number
    118                 'counter0': i,
    119                 'counter': i+1,
    120                 # reverse counter iteration numbers
    121                 'revcounter': len_values - i,
    122                 'revcounter0': len_values - i - 1,
    123                 # boolean values designating first and last times through loop
    124                 'first': (i == 0),
    125                 'last': (i == len_values - 1),
    126                 'parentloop': parentloop,
    127             }
    128             if unpack:
    129                 # If there are multiple loop variables, unpack the item into them.
    130                 context.update(dict(zip(self.loopvars, item)))
    131             else:
    132                 context[self.loopvars[0]] = item
    133             for node in self.nodelist_loop:
    134                 nodelist.append(node.render(context))
    135             if unpack:
    136                 # The loop variables were pushed on to the context so pop them
    137                 # off again. This is necessary because the tag lets the length
    138                 # of loopvars differ to the length of each set of items and we
    139                 # don't want to leave any vars from the previous loop on the
    140                 # context.
    141                 context.pop()
     113        if len_values:
     114            if self.reversed:
     115                values = reversed(values)
     116            unpack = len(self.loopvars) > 1
     117            for i, item in enumerate(values):
     118                context['forloop'] = {
     119                    # shortcuts for current loop iteration number
     120                    'counter0': i,
     121                    'counter': i+1,
     122                    # reverse counter iteration numbers
     123                    'revcounter': len_values - i,
     124                    'revcounter0': len_values - i - 1,
     125                    # boolean values designating first and last times through loop
     126                    'first': (i == 0),
     127                    'last': (i == len_values - 1),
     128                    'parentloop': parentloop,
     129                }
     130                if unpack:
     131                    # If there are multiple loop variables, unpack the item into them.
     132                    context.update(dict(zip(self.loopvars, item)))
     133                else:
     134                    context[self.loopvars[0]] = item
     135                for node in self.nodelist_loop:
     136                    nodelist.append(node.render(context))
     137        else:
     138            for node in self.nodelist_loop_empty:
     139                 nodelist.append(node.render(context))
    142140        context.pop()
    143141        return nodelist.render(context)
    144142
     
    583581            raise TemplateSyntaxError, "'for' tag received an invalid argument: %s" % token.contents
    584582
    585583    sequence = parser.compile_filter(bits[in_index+1])
    586     nodelist_loop = parser.parse(('endfor',))
     584    nodelist_loop = parser.parse(('else', 'endfor',))
     585    token = parser.next_token()
     586    if token.contents == 'else':
     587        nodelist_loop_false = parser.parse(('endfor',)) #ALTERADO
     588    else:
     589        nodelist_loop_false = NodeList()
    587590    parser.delete_first_token()
    588     return ForNode(loopvars, sequence, reversed, nodelist_loop)
     591    return ForNode(loopvars, sequence, reversed, nodelist_loop, nodelist_loop_false)
    589592do_for = register.tag("for", do_for)
    590593
    591594def do_ifequal(parser, token, negate):
Back to Top