Source code for foundry.env
"""Jinja2 environment creation and template rendering."""
from __future__ import annotations
from typing import TYPE_CHECKING
import jinja2
if TYPE_CHECKING:
from pathlib import Path
[docs]
def create_jinja_env(
*template_dirs: Path,
) -> jinja2.Environment:
"""Create a Jinja2 environment for code generation.
The returned environment has ``trim_blocks`` and
``lstrip_blocks`` enabled so that block tags
(``{% if %}``, ``{% for %}``, etc.) do not add extra blank
lines to the rendered output.
Args:
*template_dirs: One or more directories to search for
templates. Earlier directories take priority.
Returns:
A configured :class:`jinja2.Environment`.
"""
return jinja2.Environment(
loader=jinja2.FileSystemLoader(
[str(template_dir) for template_dir in template_dirs],
),
trim_blocks=True,
lstrip_blocks=True,
keep_trailing_newline=True,
undefined=jinja2.StrictUndefined,
autoescape=False, # noqa: S701 — generating source, not HTML
)
[docs]
def render_template(
env: jinja2.Environment,
template_name: str,
**context: object,
) -> str:
r"""Render *template_name* against *context* and return the raw result.
Every jinja call in foundry/kiln flows through this helper so
whitespace policy lives at the call site, not hidden inside a
render wrapper. Callers handle trimming themselves:
* Inline code snippets typically want ``.strip()``.
* Whole-file output wants ``.rstrip() + "\n"``.
* Slot contributions that the outer template controls
typically want the raw output, unmodified.
Args:
env: The Jinja2 environment to use.
template_name: Template path relative to the environment's
template directories.
**context: Template context variables.
Returns:
The rendered template, exactly as jinja produced it.
"""
return env.get_template(template_name).render(**context)