{# Recursive macro to render JSON values with syntax highlighting and collapsible objects/arrays. Usage: {{ render_json(value, is_last) }} - value: The JSON value to render (can be object, array, string, number, boolean, or null) - is_last: Whether this is the last item in a parent container (controls trailing comma) #} {% macro render_json(value, is_last=true) %} {#- Check for null/undefined FIRST since none passes other type checks -#} {%- if value is undefined or value is none -%} null{% if not is_last %},{% endif %} {%- elif value == true -%} true{% if not is_last %},{% endif %} {%- elif value == false -%} false{% if not is_last %},{% endif %} {%- elif value is string -%} "{{ value | e }}"{% if not is_last %},{% endif %} {%- elif value is number -%} {{ value }}{% if not is_last %},{% endif %} {%- elif value is mapping -%} {# Object #} {%- set items = value | items -%} {%- if items | length == 0 -%} {}{% if not is_last %},{% endif %} {%- else -%}
{ {{ items | length }} {% if items | length == 1 %}key{% else %}keys{% endif %}
{%- for item in items -%}
"{{ item[0] }}": {{ render_json(item[1], loop.last) }}
{%- endfor -%}
}{% if not is_last %},{% endif %}
{%- endif -%} {%- elif value is iterable -%} {# Array #} {%- if value | length == 0 -%} []{% if not is_last %},{% endif %} {%- else -%}
[ {{ value | length }} {% if value | length == 1 %}item{% else %}items{% endif %}
{%- for item in value -%}
{{ render_json(item, loop.last) }}
{%- endfor -%}
]{% if not is_last %},{% endif %}
{%- endif -%} {%- else -%} "{{ value | e }}"{% if not is_last %},{% endif %} {%- endif -%} {% endmacro %}