Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2: Create new row for every 3 items

Tags:

flask

jinja2

Currently for every article in articles a new div with class span4 is created. Instead for each row I would like to limit it's content to three span's and create a new row once that limit has been reached. How can I best implement this?

{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
  <legend></legend>
  <div class="row-fluid" id="main">
      {% for article in articles %}
      <div class="span4">
          <div class="thumbnail">
              <a href="{{ article.url }}"><img src="http://placehold.it/300x150/483CB4"></a>
              <div class="caption">
                  <h4><a href="{{ article.url }}">{{ article.title }}</a></h4>
                  <p> {{ article.summary }}</p>
              </div>
              <legend></legend>
              <a class="btn" href="#"><i class="icon-thumbs-up"></i></a>
              <a class="btn" href="#"><i class="icon-thumbs-down"></i></a>
          </div>
      </div>
      {% endfor %}
  </div>
</div>
{% endblock %}

Goal:

<div class="row">
  <div class="span4">article[0]</div>
  <div class="span4">article[1]</div>
  <div class="span4">article[2]</div>
</div>
<div class="row">
  <div class="span4">article[3]</div>
  <div class="span4">article[4]</div>
  <div class="span4">article[5]</div>
</div>
like image 821
cryptojuice Avatar asked Jul 22 '13 21:07

cryptojuice


2 Answers

The best way to do this is to use the built in batch filter to break up your list into groups of three:

{% for article_row in articles | batch(3, '&nbsp;') %}
<div class="row">
    {% for article in article_row %}
    <div class="span4">{{ article }}</div>
    {% endfor %}
</div>
{% endfor %}
like image 59
Sean Vieira Avatar answered Nov 05 '22 19:11

Sean Vieira


You can use loop.index0 and loop.last inside the for loop. Here is the for-loop documentation.

Example:

{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
  <legend></legend>
  <div class="row-fluid" id="main">
      {% for article in articles %}
      {% if loop.index0 % 3 == 0 %}
      <div class="row">
      {% endif %}
          <div class="span4">
              ...
          </div>
      {% if loop.index0 % 3 == 2 or loop.last %}
      </div>
      {% endif %}
      {% endfor %}
  </div>
</div>
{% endblock %}

The loop.last clause should close the last row even if there were less than 3 items. <div> should start when loop.index0 gives 0 as the remainder and should end when 2 is the remainder

Another alternative would be to group the items into rows before passing them into the template, then you can just issue two for-loops one inside the other.

like image 7
Miguel Avatar answered Nov 05 '22 20:11

Miguel