Search code examples
jinja2jinja2-cli

Jinja Template - list


Below are my input.yaml and my template.jinja:

input.yaml:

animals:
  my_pets:
  - species:
      name: "cat"
      age: "28"
  - species:
      name: "dog"
      age: "10"

template.jinja

{%- for pet in animals.my_pets %}
Type: {{ pet.species.name }}
Name: {{ pet.species.age }}
{%- endfor %}

The result should be like the input.yaml

animals:
  my_pets:
  - species:
      name: "cat"
      age: "28"
  - species:
      name: "dog"
      age: "10"

For sure something is not right on my template as it doesn't render the expected structure but I don't find what.


I've made some modification and somehow it work, but not as intended.

new_input.yaml:

my_pets:
- species:
  - name: "cat"
  - age: "28"
- species:
  - name: "dog"
  - age: "10"

new_template.jinja:

my_pets:
{%- for intf in my_pets %}
  {%- for i in intf.species %}
    {%- for key,value in i.items() %}
  - species:
     - {{ key }}: "{{ value }}"
    {%- endfor %}
  {%- endfor %}
{%- endfor %}

The new_output is like this:

  my_pets:
  - species:
     - name: "cat"
  - species:
     - age: "28"
  - species:
     - name: "dog"
  - species:
     - age: "10"

But it should be like this:

animals:
  my_pets:
  - species:
      name: "cat"
      age: "28"
  - species:
      name: "dog"
      age: "10"

Solution

  • In a loop like:

    {%- for key,value in dict.items() %}
    {%- endfor %}
    

    What you are doing is to loop on the different attributes of a dictionary — in your case name and age, so:

    1. you should not start your line with a - or you will create a list:
      {%- for key,value in dict.items() %}
        {{ key }}: "{{ value }}"
      {%- endfor %}
      
    2. the loop will iterate on each attribute of the dictionary, so, your parent attribute, species, should be on top of the loop, not inside it:
      - species:
      {%- for key,value in dict.items() %}
          {{ key }}: "{{ value }}"
      {%- endfor %}
      

    Given your input, this loop will recreate the same list of dictionaries as inputted:

    my_pets:
    {%- for pet in animals.my_pets %}
      - species:
      {%- for key, value in pet.species.items() %}
          {{ key }}: "{{ value }}"
      {%- endfor %}
    {%- endfor %}