Iterating Over Lists in Jinja: Loops
Jinja provides powerful looping constructs to iterate over lists, making it easy to dynamically generate JSON arrays or other data structures. In this section, we'll explore how to use for
loops effectively in Jinja, with an emphasis on practical examples and best practices.
Basic Syntax for Loops
The for
statement allows you to iterate over a list or any iterable object. Basic Structure:
{% for item in list %}
{{ item }}
{% endfor %}
Example: Iterating Over a List
Suppose request.body.servicePacks
is a list like this:
["pack1", "pack2", "pack3"]
Template Example:
[
{%- for item in request.body.servicePacks -%}
"{{ item }}"{% if not loop.last %},{% endif %}
{%- endfor -%}
]
Rendered Output:
["pack1","pack2","pack3"]
Explanation:
- Loop Variables:
- item iterates through the values in request.body.servicePacks.
- Each iteration processes one value from the list.
- Avoiding Extra Commas:
- The condition
{% if not loop.last %},{% endif %}
ensures that commas are added only between elements and not after the last element.
- The condition
- Whitespace Control:
{%-
and-%}
are used to control unnecessary spaces and line breaks in the output.
Exercise
In the template playground, copy/paste the following in the Context panel
{
"request":
{
"body": {"servicePacks": ["pack1", "pack2", "pack3"] }
}
}
And test the template examples above
The loop Object
Within a for
loop, Jinja provides a special loop object with useful attributes for additional control over iterations.
Common loop Attributes
loop.index
: The current iteration index (1-based).loop.index0
: The current iteration index (0-based).loop.revindex
: The remaining iterations (1-based).loop.revindex0
: The remaining iterations (0-based).loop.first
: True if it's the first iteration.loop.last
: True if it's the last iteration.loop.length
: The total number of items in the iterable.
Advanced Example: Numbered List
If you want to generate a numbered list based on request.body.servicePacks
: Template Example:
[
{% for item in request.body.servicePacks -%}
{ "index": {{ loop.index0 }}, "value": "{{ item }}" }{% if not loop.last %},{% endif %}
{% endfor %}
]
Rendered Output:
[
{ "index": 0, "value": "pack1" },
{ "index": 1, "value": "pack2" },
{ "index": 2, "value": "pack3" }
]
Explanation:
loop.index0
gives the 0-based index for each item in the list.- Each item is included in a dictionary structure with an index and value.
Nested Loops
You can nest for
loops to iterate over multi-dimensional lists or dictionaries. Input:
{
"servicePacks": [
["pack1a", "pack1b"],
["pack2a", "pack2b"]
]
}
Template Example:
[
{% for sublist in request.body.servicePacks -%}
[
{% for item in sublist -%}
"{{ item }}"{% if not loop.last %},{% endif %}
{% endfor %}
]{% if not loop.last %},{% endif %}
{% endfor %}
]
Rendered Output:
[
[
"pack1a",
"pack1b"
],
[
"pack2a",
"pack2b"
]
]
Conditional Loops in Jinja
Jinja allows you to combine for loops with if conditions to filter items while iterating. This is especially useful when generating lists or JSON objects dynamically, where specific items must meet certain criteria. This also helps managing commas in conditional loops, as they should only appear between items and not at the end.
Combining for and if
You can add an if
statement inside a for
loop to conditionally process items.
Basic Example
Input List:
{"fruits": ["apple", "banana", "cherry", "date"]}
Template:
[
{% for fruit in fruits if fruit != "banana" -%}
"{{ fruit }}"{% if not loop.last %},{% endif %}
{% endfor %}
]
Output:
[
"apple",
"cherry",
"date"
]
Explanation:
- The
if fruit != "banana"
filters out"banana"
. {% if not loop.last %},{% endif %}
ensures that commas are placed only between items. Another possible template is
[
"{{ fruits | select('ne', 'banana') | join('", "') }}'
]
Here , we have
select('ne', 'banana')
that filters outbanana
(not equal).join('", "')
that joins the filtered items with,
as the separator. This last method is only suitable for flat lists.
Summary
The for
loop in Jinja is a versatile tool for iterating over lists and generating dynamic content. By combining it with the loop object and conditional logic, you can create flexible and efficient templates for JSON or any structured data format.