WebhockTransfer/app/templates.py

44 lines
1.5 KiB
Python

import re
from typing import Any, Dict
import jinja2
# Create a minimal Jinja2 environment for text templates.
# Use StrictUndefined so missing variables raise exceptions during rendering.
ENV = jinja2.Environment(
undefined=jinja2.StrictUndefined,
autoescape=False,
)
def _convert_braced_format_to_jinja(template: str) -> str:
"""
Convert simple `{var}` style placeholders into Jinja `{{ var }}` so legacy templates keep working.
This will not touch existing `{{ }}` or `{% %}`.
"""
# Skip conversion if template already contains jinja markers
if ("{{" in template) or ("{%" in template):
return template
# Replace single-brace simple identifiers like {a_b} or {a.b} -> {{ a_b }} or {{ a.b }}
pattern = re.compile(r'(?<!\{)\{([A-Za-z0-9_\.]+)\}(?!\})')
return pattern.sub(r'{{ \1 }}', template)
def safe_render(template_str: str, context: Dict[str, Any]) -> str:
"""
Safely render a template string using Jinja2 with StrictUndefined.
- Accepts legacy `{var}` placeholders by converting them to Jinja style.
- Raises jinja2 exceptions when rendering fails.
"""
if template_str is None:
raise ValueError("template_str is None")
tpl = _convert_braced_format_to_jinja(template_str)
jtpl = ENV.from_string(tpl)
# Jinja expects normal Python types in context; if context contains Pydantic models,
# they should be converted by caller to plain dicts.
return jtpl.render(**context)