Skip to content

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:

jinja
{% for item in list %}
    {{ item }}
{% endfor %}

Example: Iterating Over a List

Suppose request.body.servicePacks is a list like this:

json
["pack1", "pack2", "pack3"]

Template Example:

jinja
[
    {%- for item in request.body.servicePacks -%}
        "{{ item }}"{% if not loop.last %},{% endif %}
    {%- endfor -%}
]

Rendered Output:

json
["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.
  • 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

json
{
"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:

jinja
[
    {% for item in request.body.servicePacks -%}
        { "index": {{ loop.index0 }}, "value": "{{ item }}" }{% if not loop.last %},{% endif %}
    {% endfor %}
]

Rendered Output:

json
[
    { "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:

json
{
    "servicePacks": [
        ["pack1a", "pack1b"],
        ["pack2a", "pack2b"]
    ]
}

Template Example:

jinja
[
    {% 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:

json
 [
    [
        "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:

json
{"fruits": ["apple", "banana", "cherry", "date"]}

Template:

jinja
[
    {% for fruit in fruits if fruit != "banana" -%}
        "{{ fruit }}"{% if not loop.last %},{% endif %}
    {% endfor %}
]

Output:

json
[
    "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
jinja
[
    "{{ fruits | select('ne', 'banana') | join('", "') }}'
]

Here , we have

  • select('ne', 'banana') that filters out banana (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.