Jinja, recursive output from json

Viewed 184

I can't output the following json object in the jinja template engine

all json object

Abbreviated output:

{
  "data": {
    "domain.org": {
      "type": "folder",
      "children": [
        {
          "data": {
            "type": "folder",
            "children": [
              {
                "last-id.txt": {
                  "type": "file",
                  "children": {}
                }
              }
            ]
          }
        },
        {
          "layouts": {
            "type": "folder",
            "children": [
              {
                "_default": {
                  "type": "folder",
                  "children": [
                    {
                      "single.html": {
                        "type": "file",
                        "children": {}
                      }
                    }
                  ]
                }
              },
              {
                "robots.txt": {
                  "type": "file",
                  "children": {}
                }
              }
            ]
          }
        },
        {
          "content": {
            "type": "folder",
            "children": [
              {
                "posts": {
                  "type": "folder",
                  "children": [
                    {
                      "post6.md": {
                        "type": "file",
                        "children": {}
                      }
                    }]
                }
              }]
          }
        }]
    }
  }
}

Following the example from the official documentation, I try to derive it as follows

{% set list = data['data'] %}
    <ul>
        {% for key in list recursive %}
        <li>
            {{ key }}
            {% if list[key]['children'] %}
                <ul>{{ loop(list[key]['children']) }}</ul>
            {% endif %}    
        </li>
                                                    
        {% endfor %}   

    </ul>
{% endif %}

I'm trying to go through the loop recursively, but nothing works, I keep getting an error:

jinja2.exceptions.UndefinedError: dict object has no element {'data': {'type': 'folder', 'children': [{'last-id.txt': {'type': 'file', 'children': {}}}]}}

How can I display such an object?

1 Answers

Something like this, using a recursive macro, might be closer to what you want, since your structure has both lists (children) and dicts (the objects within).

{%- macro dump_dict(d) -%}
    <ul>
    {% for key, value in d.items() %}
        <li>{{ key }}
        {% if value.children %}
            {% for child in value.children -%}
                {{ dump_dict(child) }}
            {%- endfor %}
        {% endif -%}
        </li>
    {%- endfor -%}
    </ul>
{%- endmacro %}

{{ dump_dict(data.data) }}

This prints out (prettified here for display)

<ul>
  <li>
   domain.org
   <ul>
    <li>
     data
     <ul>
      <li>
       last-id.txt
      </li>
     </ul>
    </li>
   </ul>
   <ul>
    <li>
     layouts
     <ul>
      <li>
       _default
       <ul>
        <li>
         single.html
        </li>
       </ul>
      </li>
     </ul>
     <ul>
      <li>
       robots.txt
      </li>
     </ul>
    </li>
   </ul>
   <ul>
    <li>
     content
     <ul>
      <li>
       posts
       <ul>
        <li>
         post6.md
        </li>
       </ul>
      </li>
     </ul>
    </li>
   </ul>
  </li>
 </ul>

Related