Django create multi colums flexible best practices - django

I want to create a picture viewer with many colums. I don' know exactly the number.
I want to respect best practices.
I have done the following code :
{% with max=4 taille=3 %}
{% for image in image_list %}
{% if nb == 1 %}
<div class="row">
{% endif %}
<div class="col-sm-{{ taille }}">
{{ image.name }}
</div>
{% if nb == 2 %}
</div>
{% endif %}
{% nb += 1 %}
{% if nb > 4 %}
{% nb = 1 %}
{% endif %}
{% endfor %}
{% endwith %}
But the templating system don't allow me to do this line :
{% nb += 1 %}
Do you have any ideas ? Thank you.

This is a quick example on how you can do this (this is for 2 column based itteration) but you can change it to your liking (replace "2" with a integer for instance):
<div class="row">
{% for image in image_list %}
<div class="col-sm-6">
{{ image.name }}
</div>
{% if not forloop.last and forloop.counter|divisibleby:"2" %}
</div>
<div class="row">
{% endfor %}
</div>

In Django Templates you can not use += 1 operator
you can use the forloop.counter
{% if forloop.counter0|divisibleby:4 %} so every 4 iterations
starting with first iteration where
counter is 0
<div class="row">
{% endif %}
<div class="col-sm-{{ taille }}">
{{ image.name }}
</div>
{% if forloop.counter0|add:"-1"|divisibleby:"4" %} also every 4 iterations
but starting with the 2nd
iteration where counter is 1
</div>
{% endif %}

Related

How to switch design for each cards in django templates

How to switch between different card designs for each data in the for loop.
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
These three cards have different designs, Currently facing trouble in switching these cards for each loop in the Django template.
{% for cont in data %}
{% ifequal forloop.counter|divisibleby:"3" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% ifnotequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifnotequal %}
{% endfor %}
Third card logic is wrong. I need to change this logic so that for each loop each cards need to be displayed alternatively. And another challenge is that after 3 loop it should close the section, since in a row only 3 cards are allowed.
<section class="section-tours" id="section-tours">
{% ifequal forloop.counter|divisibleby:"3" True %}
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
{% endifequal %}
</section>
You can use build in django cycle template tag for this. You can update your html and add the cycle template tag like below to change design of 1st, 2nd and 3rd card.
{% for cont in data %}
<div class="{% cycle 'col-1-of-3' 'col-2-of-3' 'col-3-of-3' %}">
<div class="card">
...
</div>
</div>
{% endfor %}
I hope this will help you :)
Section is closed after printing 3 cards.
<section class='section-tours' id='section-tours'>
<div class="row">
{% for cont in data %}
{% cycle 'tools/col-1-of-3.html' 'tools/col-2-of-3.html' 'tools/col-3-of-3.html' as tmp silent %}
{% include tmp %}
{% cycle "" "" "</div> </section><section class='section-tours' id='section-tours'>" %}
{% endfor %}
</section>
Test the below code and tell me if it helps, since I have not tested it.
I have sliced the for loop for first three values, if you want to repeat the same change the slice for same code.
{% for cont in data|slice:":3" %} #i have sliced it for first three values only
{% if forloop.first %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endif %}
{% ifequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% if forloop.last %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endif %}
{% endfor %}

How do i implement a working if Statement in twig? mine isnt working

im trying to do a simple IF statement while templating with twig. Appears that it gets ignored and the following code is read everytime. Should be Pretty simple but does just not work.
{% extends "_layout" %}
{% block content %}
<div class="box">
{% set x = 1 %}
{% for entry in craft.entries.section('news') %}
{% if x % 3 == 0 %}
<div class="row">
</div>
{% endif %}
{% set x =+ 1 %}
<div class="beitrag col l4 m12 s12">
<h3 class="beitrag_titel">{{ entry.title }}</h3> <p>{{ entry.textnews }}</p>
</div>
{% endfor %}
</div>
{% endblock %}
i want the code to do a new "row" div every third entry. All he does is do a new one every time.
thx for the answers
Your assignment of x is wrong. there is no postincrement in twig.
At this point your just setting x to +1 every time. You should be using {% set x = x + 1 %}
Some notes, it not necessary to keep track of an extra counter in the for loop as you could use loop.index or loop.index0, starting at 1 and 0 respectively.
Also you could use the test is divisible by for more readability
{% for i in 0..10 %}
{% if loop.index is divisible by(3) %}
{{ loop.index }} is divisible by 3
{% endif %}
{% endfor %}
demo
To solve html issues with rows you could also use batch
<div class="box">
{% for row in data|batch(3) %}
{% for value in row %}
<div class="beitrag col l4 m12 s12">
{{ value }}
</div>
{% endfor %}
<div class="row"></div>
{% endfor %}
</div>
demo
From your (deleted) comment, if you wanted the content to go inside the row, u 'd need to adapt the code as following
<div class="box">
{% set x = 1 %}
{% for entry in entries %}
{% if loop.first %}
<div class="row">
{% endif %}
<div class="col l4 m12 s12">
<h3 class="beitrag_titel">{{ entry.title }}</h3>
<p>{{ entry.textnews }}</p>
</div>
{% if x is divisible by(3) and not loop.last %}
</div>
<div class="row">
{% endif %}
{% set x = x + 1 %}
{% if loop.last and entries|length is not divisible by(3) %}
</div>
{% endif %}
{% endfor %}
</div>
demo
But then you are def better of with batch
<div class="box">
{% for row in entries|batch(3) %}
<div class="row">
{% for value in row %}
<div class="beitrag col l4 m12 s12">
<h3>{{ value.title }}</h3>
<p>{{ value.textnews }}</p>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
demo

Django template skip line every two iteration

I have the following html structure:
<div class="row>
<div class="box"></div>
<div class="box"></div>
</div>
I am using pagination feature on Django to pass on 6 items per page.
How would I go about iterating over the paginator generated object list while wrapper each two box divs with row div?
You can use the forloop.counter in the template
{% for obj in obj_list %}
{% if forloop.counter0|divisibleby:2 %}
<div class="row">
{% endif %}
<div class="box"></div>
<div class="box"></div>
{% if forloop.counter|divisibleby:2 %}
</div>
{% endif %}
{% else %}
Nothing to show
{% endfor %}
and if there are odd number of elements in the list, then it would not have a trailing div. I will let you figure out that scenario by yourself. (it is pretty simple)
Documentation for the forloop.counter0 can be found here
Documentation for divisibleby can be found here
I agree with karthikr's solution, but it doesn't print the </div> if you have 3, 5 items...
You have to add a forloop.last to handle that case:
{% for obj in obj_list %}
{% if forloop.counter0|divisibleby:2 %}
<div class="row">
{% endif %}
<div class="box"></div>
<div class="box"></div>
{% if forloop.counter|divisibleby:2 or forloop.last %}
</div>
{% endif %}
{% else %}
Nothing to show
{% endfor %}

How can I check for loop count? (and whether it is even or odd) [duplicate]

This question already has answers here:
How do I get odd and even values in a Django for loop template?
(4 answers)
Closed 8 years ago.
{% for p in posts %}
<div id="even">{{ p.title }}</div>
<div id="odd">{{ p.title }}</div>
{% endfor %}
I need create something like this:
{% for p in posts %}
{% if forloop_count is even %}
<div id="even">{{ p.title }}</div>
{% else %}
<div id="odd">{{ p.title }}</div>
{% endif %}
{% endfor %}
How can I check for loop count? (and whether it is even or odd)
Is that your real underlying requirement, or are you simply trying to cycle between two div classes? Do they have to be odd/even, or just alternating?
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
Reference: https://docs.djangoproject.com/en/dev/ref/templates/builtins/
In your case it would be:
{% for p in posts %}
<div id="{% cycle 'even' 'odd' %}">{{ p.title }}</div>
{% endif %}
Use divisableby
{% for p in posts %}
{% if forloop.counter|divisibleby:"2" %} {# is even #}
<div id="even">{{ p.title }}</div>
{% else %}
<div id="odd">{{ p.title }}</div>
{% endif %}
{% endfor %}
or if its simply for a id use cycle e.g.
{% cycle 'odd' 'even' %}

How do I get odd and even values in a Django for loop template?

I have this code
{% for o in some_list %}
Now I want to do some stuff if I am on an even line. How can I do that?
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#divisibleby
{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}
In first level cycle:
{% cycle 'odd' 'even' %}
Reference:
Documentation for cycle template tag
<div class="row">
{% for post in posts %}
{% cycle 'odd' 'even' %}
{% if cycle == 'odd' %}
<div class="col-md-6">Odd posts</div>
{% else %}
<div class="col-md-6">Even posts</div>
{% endif %}
{% endfor %}
</div>
OR
<div class="row">
{% for post in posts %}
{% if forloop.counter|divisibleby:2 %}
<div class="col-md-6">Even posts</div>
{% else %}
<div class="col-md-6">Odd posts</div>
{% endif %}
{% endfor %}
</div>
<div class="row">
{% for post in posts %}
{% if loop.index is divisibleby 2 %}
<div class="col-md-6">Even posts</div>
{% else %}
<div class="col-md-6">Odd posts</div>
{% endif %}
{% endfor %}
</div>
http://mitsuhiko.pocoo.org/jinja2docs/html/templates.html#id3