如何获取Jinja2模板构建过程中涉及的所有模板文件列表?
获取Jinja2模板构建时涉及的所有模板文件列表
我有一个使用include和extends语句引用其他模板的Jinja2模板,希望获取构建该模板时涉及的所有模板文件列表。现有实现代码如下:
import jinja2 environment = jinja2.Environment() template = environment.get_template("mynestedtemplate.html") template.render(vartest="Hello")
目前仅找到可列出模板块的jinja2.Template.blocks方法,请问是否存在能列出所有被使用模板的方法?
解决方案
Jinja2本身没有直接提供获取所有依赖模板的公开方法,但可以通过以下两种方式实现:
方法一:自定义模板加载器追踪
继承Jinja2的模板加载器(比如FileSystemLoader),重写get_source方法,在每次加载模板时记录模板路径:
import jinja2 from jinja2.loaders import FileSystemLoader class TrackingLoader(FileSystemLoader): def __init__(self, searchpath): super().__init__(searchpath) self.loaded_templates = set() def get_source(self, environment, template): source, filename, uptodate = super().get_source(environment, template) self.loaded_templates.add(filename) return source, filename, uptodate # 使用自定义加载器 loader = TrackingLoader("./templates") env = jinja2.Environment(loader=loader) template = env.get_template("mynestedtemplate.html") template.render(vartest="Hello") # 查看所有加载的模板 print(loader.loaded_templates)
方法二:解析模板AST(抽象语法树)
通过Jinja2的AST解析器遍历模板节点,提取Include和Extends语句中的模板名称,再递归解析这些模板:
import jinja2 from jinja2.nodes import Include, Extends def get_all_templates(env, template_name, visited=None): if visited is None: visited = set() if template_name in visited: return visited # 获取模板并解析AST template = env.get_template(template_name) visited.add(template.filename) # 遍历AST节点 for node in list(template.root.find_all((Include, Extends))): # 获取引用的模板名称 ref_template = node.template.value get_all_templates(env, ref_template, visited) return visited # 使用示例 env = jinja2.Environment(loader=jinja2.FileSystemLoader("./templates")) all_templates = get_all_templates(env, "mynestedtemplate.html") print(all_templates)
注意事项
- 方法一能准确追踪所有实际加载的模板(包括条件加载的模板),但需要确保所有模板都通过该加载器加载。
- 方法二是静态解析,能找到模板中声明引用的所有模板,但无法处理动态生成模板名称的情况(比如
{% include some_var %})。
内容的提问来源于stack exchange,提问作者G M
相关产品推荐
相关产品推荐

