18

I'm creating a catalogue, where there is a list of items of undefined length. I want to spit it out in rows with three columns each. So I have the following html:

<div class="row">
    <div class="three columns">item 1
    </div>
    <div class="three columns">item 2
    </div>
    <div class="three columns">item 3
    </div>
</div>
<div class="row">
    <div class="three columns">item 4
    </div>
    <div class="three columns">item 5
    </div>
    <div class="three columns">item 6
    </div>
</div>

I'm stuck as to how I can implement this as a django template? How can I split it up so that a new row starts after three items?

babbaggeii
  • 7,577
  • 20
  • 64
  • 118

4 Answers4

46

Try something like this:

<div class="row">
{% for item in items %}
    <div class="three columns">{{ item }}
    </div>
    {% if forloop.counter|divisibleby:3 %}
</div>
<div class="row">
    {% endif %}
{% endfor %}
</div>
jpic
  • 32,891
  • 5
  • 112
  • 113
5

You could try to create a custom template filter, that would return a list of list of 3-items.

Quick attempt :

@register.filter
def splitByThree(data):
    return [l[i:i+3] for i in range(0, len(l), 3)]

And then in your template :

{% load splitByThree %}

{% for list in data|splitByThree %}
<div class="row">
{% for item in list %}
<div class="three columns">{{ item }}</div>
{% endfor %}
</div>
{% endfor %}
pistache
  • 5,782
  • 1
  • 29
  • 50
  • 1
    There is a set of more flexible ways to split list into list of lists here - http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python – Igor Oct 24 '12 at 11:27
4

You can use forloop.counter variable and divisibleby filter. The code will be close to this:

{% for item in items %}
    {% if forloop.first %}
        <div class="row">
    {% endif %}
    <div class="three columns">{{ item }}</div>
    {% if forloop.counter|divisibleby:"3" %}
        </div>
        {% if not forloop.last %}
            <div class="row">
        {% endif %}
    {% endif %}
    {% if forloop.last %}
         </div>
    {% endif %}
{% endfor %}
Igor
  • 3,129
  • 1
  • 21
  • 32
1

Sorry don't have enough reputation to just comment jpic's answer(the accepted one), for Jinja2, use:

<div class="row">
{% for item in items %}
    <div class="three columns">{{ item }}
    </div>
    {% if loop.index is divisibleby(3) %}
</div>
<div class="row">
    {% endif %}
{% endfor %}
</div>

details are here.

hexcola
  • 41
  • 3