Jinja2如何仅加载include引用不渲染其余标签实现模板扁平化
Jinja2 没有原生内置的公开API直接实现仅展开include标签、不执行其他模板逻辑的模板扁平化功能,但可以通过解析模板AST(抽象语法树)的方式自定义实现该需求,具体思路如下:
- 首先用Jinja2自带的语法解析能力加载目标模板的抽象语法树
- 遍历语法树节点,仅匹配
Include类型的节点,递归将该节点替换为被引入模板的语法树内容,其余所有节点(包括循环、变量占位符等)全部保留原始结构不做处理 - 最后将处理完成的语法树重新转换为模板字符串,即可得到你需要的仅展开所有
include引用的扁平化结果
下面是基础实现的示例代码:
from jinja2 import Environment, FileSystemLoader from jinja2.nodes import Include def flatten_template_includes(env: Environment, template_name: str, processed_tpls: set = None): # 避免循环引入死循环 if processed_tpls is None: processed_tpls = set() if template_name in processed_tpls: return "" processed_tpls.add(template_name) # 加载模板原始内容并解析为AST tpl_source = env.loader.get_source(env, template_name)[0] ast = env.parse(tpl_source) result_parts = [] for node in ast.body: if isinstance(node, Include): # 递归展开被引入的模板 included_content = flatten_template_includes(env, node.template.value, processed_tpls.copy()) result_parts.append(included_content) else: # 非Include节点直接输出原始语法字符串 result_parts.append(str(node)) return "".join(result_parts) # 示例使用:加载当前目录下的模板文件 if __name__ == "__main__": env = Environment(loader=FileSystemLoader("./")) flat_content = flatten_template_includes(env, "tmpl.j2") print(flat_content)
注意上述代码仅做基础功能演示,实际使用时需要自行适配空格对齐、模板路径别名、特殊字符转义等边界场景。
内容的提问来源于stack exchange,提问作者Philippe Hebert
相关产品推荐
相关产品推荐

