Nunjucks advanced loops
2 min read
Nunjucks is a powerful template engine that allows to loop through arrays and also objects ๐
Loop though an array #
{% set animals = ['๐ฑ', '๐ถ', '๐บ'] %}
{% for item in animals %}
Value: {{ item }}
{% endfor %}
Value: ๐ฑ
Value: ๐ถ
Value: ๐บ
Loop though an object #
{% set animal = {
name: 'cat',
emoji: '๐ฑ'
} %}
{% for key, value in animal %}
{{ key }}: {{ value }}
{% endfor %}
Note that we have to declare the two parameters of the loop key, value
.
name: cat
emoji: ๐ฑ
The iterable
property #
In Twig exists an intresting property, iterable
that checks if a variable can be iterable in a for loop:
Loop through an array:
{% set animals = ['๐ฑ', '๐ถ', '๐บ'] %}
{% if animals is iterable %}
{% for item in animals %}
Value: {{ item }}
{% endfor %}
{% else %}
Not iterable: {{ animal }}
{% endif %}
Value: ๐ฑ
Value: ๐ถ
Value: ๐บ
Loop through an object:
{% set animals = {
name: 'cat',
emoji: '๐ฑ'
} %}
{% if animals is iterable %}
{% for item in animals %}
Value: {{ item }}
{% endfor %}
{% else %}
Not iterable: {{ animal }}
{% endif %}
Value: cat
Value: ๐ฑ
๐งจ !important
Please note that
iterable
is a Twig property and can have unexpected results in Nunjucks template engine.
In Twig a string is not iterable:
{% set animal = 'cat' %}
{% if animal is iterable %}
Iterable!
{% for item in animal %}
Value: {{ item }}
{% endfor %}
{% else %}
Not iterable!
{{ animal }}
{% endif %}
Twig output
Not iterable!
cat
but if we run the same code in Nunjucks, we discover that a string is iterable ๐คฏ
Nunjucks output
Iterable!
Value: c
Value: a
Value: t
Accessing the parent loop #
Nunjucks provides in its loops the loop
property.
From the docs the loop.index
is
the current iteration of the loop (1 indexed)
But what if we have two nested loops and we want to access to the parent loop?
Workaround: save the loop index as row number! ๐
In this example we have a matrix content: two rows and each row has one ore more cells. If we want to print all cells content and position, we have to:
-
loop (parent loop) through the rows
-
loop (child loop) through the columns
-
get the content inside each cell
{% set animals = [
['๐ฑ', '๐ถ', '๐บ'],
['๐']
] %}
<table>
{% for row in animals %}
{# new row #}
<tr>
{% set rowloop = loop %}
{% for cell in row %}
<td>
row (rowloop.index):{{ rowloop.index }}
column (loop.index): {{ loop.index }}
cell: {{ cell }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
HTML output
<table>
{# new row #}
<tr>
<td>
row (rowloop.index):1
column (loop.index): 1
cell: ๐ฑ
</td>
<td>
row (rowloop.index):1
column (loop.index): 2
cell: ๐ถ
</td>
<td>
row (rowloop.index):1
column (loop.index): 3
cell: ๐บ
</td>
</tr>
{# new row #}
<tr>
<td>
row (rowloop.index):2
column (loop.index): 1
cell: ๐
</td>
</tr>
</table>
๐ More info