43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""通用 HTML 模板渲染工具。
|
|
|
|
目标:
|
|
1. 把页面结构/样式从 Python 代码中抽离到 .html 模板文件;
|
|
2. Python 只负责组装数据,模板负责展示;
|
|
3. 后续改 UI 时只改模板文件,不改业务代码。
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Dict
|
|
|
|
from jinja2 import Environment, FileSystemLoader, TemplateNotFound, select_autoescape
|
|
|
|
|
|
class HtmlTemplateRenderer:
|
|
"""基于 Jinja2 的 HTML 模板渲染器。"""
|
|
|
|
def __init__(self, template_root: Path = None):
|
|
# 默认以仓库根目录作为模板根路径,确保可通过相对路径定位模板文件。
|
|
root = template_root or Path(__file__).resolve().parents[1]
|
|
self.template_root = Path(root).resolve()
|
|
self.env = Environment(
|
|
loader=FileSystemLoader(str(self.template_root)),
|
|
autoescape=select_autoescape(enabled_extensions=("html", "xml")),
|
|
trim_blocks=True,
|
|
lstrip_blocks=True,
|
|
)
|
|
|
|
def render(self, template_path: str, context: Dict[str, Any]) -> str:
|
|
"""渲染模板并返回完整 HTML 字符串。"""
|
|
normalized = str(template_path or "").replace("\\", "/").strip()
|
|
if not normalized:
|
|
raise ValueError("template_path 不能为空")
|
|
try:
|
|
template = self.env.get_template(normalized)
|
|
except TemplateNotFound as e:
|
|
raise FileNotFoundError(
|
|
f"模板文件不存在: {normalized} (root={self.template_root})"
|
|
) from e
|
|
return template.render(**(context or {}))
|
|
|