spaceapi-server/spaceapi_server/template/__init__.py

55 lines
1.6 KiB
Python

import json
import jinja2
# The Jinja2 environment
__ENV = None
def _env_init(force: bool = False):
"""
Initialize the Jinja2 environment.
:param force: If true, force reload the environment.
"""
global __ENV
if __ENV is None or force:
# Use json.dumps as finalizer in order to preserve complex data structures
__ENV = jinja2.Environment(finalize=json.dumps)
return __ENV
def render(template: str):
"""
Render the given string as a Jinja2 template.
:param template: The template string to render.
"""
# Make sure the Jinja2 environment is initialized
env = _env_init()
# Create a Jinja2 template from the input string
t = env.from_string(template)
decoder = json.JSONDecoder()
# Render the template and turn the JSON dump back into complex data structures
# Only parse the first JSON object in the string, ignore the rest
obj, i = decoder.raw_decode(t.render())
return obj
def render_traverse(obj):
"""
Walk through a complex, JSON-serializable data structure, and pass
string objects through the Jinja2 templating engine.
:param obj: The object to traverse.
"""
if isinstance(obj, list):
# list -> recurse into each item
return [render_traverse(x) for x in obj]
elif isinstance(obj, dict):
# dict -> recurse into the value of each (key, value)
return {k: render_traverse(v) for k, v in obj.items()}
elif isinstance(obj, str):
# str -> template
return render(obj)
else:
# anything else -> return as-is
return obj