Jinja2 Recursive Rendering of a Deep Data Structure to YAML: Difference between revisions
Jump to navigation
Jump to search
Line 6: | Line 6: | ||
=The Template= | =The Template= | ||
<syntaxhighlight lang='jinja'> | <syntaxhighlight lang='jinja'> | ||
{%- macro recursively_render_data_structure(d, | {%- macro recursively_render_data_structure(d, overall_offset, recursion_level_indentation) -%} | ||
{%- if d is number %}{{ d }} | {%- if d is number %}{{ d }} | ||
{%- elif d is string %}"{{ d }}" | {%- elif d is string %}"{{ d }}" | ||
{%- elif d is mapping -%} | {%- elif d is mapping -%} | ||
{%- for key, value in d.items() %} | {%- for key, value in d.items() %} | ||
{{ ' ' * | {{ overall_offset }}{{ ' ' * recursion_level_indentation }}{{ key }}: {{ recursively_render_data_structure(value, overall_offset, recursion_level_indentation + 2) }} | ||
{%- endfor %} | {%- endfor %} | ||
{%- elif d is iterable %} | {%- elif d is iterable %} | ||
{%- for i in d %} | {%- for i in d %} | ||
{{ ' ' * | {{ overall_offset }}{{ ' ' * recursion_level_indentation }} - {{ recursively_render_data_structure(i, overall_offset, recursion_level_indentation + 4) }} | ||
{%- endfor %} | {%- endfor %} | ||
{%- else %}ERROR: UNKNOWN VALUE {{ d }} | {%- else %}ERROR: UNKNOWN VALUE {{ d }} | ||
Line 21: | Line 21: | ||
{%- endmacro -%} | {%- endmacro -%} | ||
{{- recursively_render_data_structure(m, 0) }} | {{- recursively_render_data_structure(m, ' ', 0) }} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 22:37, 23 August 2023
Internal
Overview
The method uses a recursive macro.
The Template
{%- macro recursively_render_data_structure(d, overall_offset, recursion_level_indentation) -%}
{%- if d is number %}{{ d }}
{%- elif d is string %}"{{ d }}"
{%- elif d is mapping -%}
{%- for key, value in d.items() %}
{{ overall_offset }}{{ ' ' * recursion_level_indentation }}{{ key }}: {{ recursively_render_data_structure(value, overall_offset, recursion_level_indentation + 2) }}
{%- endfor %}
{%- elif d is iterable %}
{%- for i in d %}
{{ overall_offset }}{{ ' ' * recursion_level_indentation }} - {{ recursively_render_data_structure(i, overall_offset, recursion_level_indentation + 4) }}
{%- endfor %}
{%- else %}ERROR: UNKNOWN VALUE {{ d }}
{%- endif %}
{%- endmacro -%}
{{- recursively_render_data_structure(m, ' ', 0) }}
The Rendering Code
The code includes a test that the rendered structure is equivalent with the input:
from pathlib import Path
import yaml
from jinja2 import Environment, FileSystemLoader
tdir = Path('.')
template = Environment(loader=FileSystemLoader(tdir)).get_template('experimental-jinja-template.yaml.j2')
yaml_data = """
config:
color: blue
size: 1
samples:
- name: venice
neighborhoods:
cannaregio: 1
castello: 2
giudecca: 3
- name: genoa
neighborhoods:
molo: 1
foce: 2
marassi: 3
- name: florence
neighborhoods:
santamaria: 1
sanmarco: 2
santacroce: 3
no-such-neighborhood:
- a1: v1
a2: v2
- b
- c
"""
m = yaml.safe_load(yaml_data)
rendered_text = template.render(m=m)
print(rendered_text)
m2 = yaml.safe_load(rendered_text)
assert m == m2