Login

range tag

Author:
marco.fucci
Posted:
May 22, 2009
Language:
Python
Version:
1.0
Tags:
template tag django
Score:
2 (after 2 ratings)

Create a list containing an arithmetic progression that can be iterated through in templates. Emulate the range syntax. You can use either numbers or variables.

Syntax:
{% num_range [start] stop [step] as some_range %}

{% for i in some_range %}
  ... do something
{% endfor %}

About the author: Take a look at my website

 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
class RangeNode(template.Node):
    def __init__(self, start, stop, step, context_name):
        if not self._isint(start):
            self.start = template.Variable(start)
        else:
            self.start = start

        if not self._isint(stop):
            self.stop = template.Variable(stop)
        else:
            self.stop = stop

        if not self._isint(step):
            self.step = template.Variable(step)
        else:
            self.step = step

        self.context_name = context_name

    def _isint(self, value):
        return isinstance(value, int)

    def _resolveint(self, value, context):
        if self._isint(value):
            return value
        return int(value.resolve(context))

    def render(self, context):
        start = self._resolveint(self.start, context)
        stop = self._resolveint(self.stop, context)
        step = self._resolveint(self.step, context)
    
        context[self.context_name] = range(start, stop, step)
        return ""

@register.tag
def num_range(parser, token):
    """
    Create a list containing an arithmetic progression that can be 
    iterated through in templates.

    If the start argument is omitted, it defaults to 0. 
    If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. 
    step must not be zero (or else ValueError is raised).
    
    see http://docs.python.org/library/functions.html#range for more details.

    Syntax:
    {% num_range [start] stop [step] as some_range %}
    
    {% for i in some_range %}
      ... do something
    {% endfor %}
    """
    bits = token.contents.split()
    len_bits = len(bits)

    if len_bits not in range(4, 7):
        raise template.TemplateSyntaxError(_('%s tag requires between three and fifth arguments') % bits[0])
    if bits[-2] != 'as':
        raise template.TemplateSyntaxError(_("last but one argument to %s tag must be 'as'") % bits[0])

    #DEFAULTS
    start, step = 0, 1

    as_index = bits.index('as')

    if as_index == 2:
        stop = bits[1]
    else:
        start, stop = bits[1], bits[2]
        
        if as_index == 4:
            step = bits[3]

    context_name = bits[-1]

    return RangeNode(start, stop, step, context_name)

More like this

  1. Template range loop by nfg 5 years, 6 months ago
  2. Template range tag by newmaniese 7 years, 2 months ago
  3. Template range filter by zalun 6 years, 4 months ago
  4. mkrange - create a range() inside a template - variable/filter support for range values by berserkpi 4 years, 11 months ago
  5. Template tag to clear cached template fragment by joao.coelho 5 years, 8 months ago

Comments

Please login first before commenting.