如何直接从文件系统加载 jinja 模板

Jinja API 文档在 pocoo.org指出:

配置 Jinja2为应用程序加载模板的最简单方法大致如下:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
这将创建一个具有默认设置的模板环境和一个在 你的申请 python 包内的 模板文件夹中查找模板的加载程序。

事实证明,这并不那么简单,因为您必须创建/安装一个包含模板的 python 包,这会带来许多不必要的复杂性,特别是在您无意分发代码的情况下。你可以参考关于 给你给你的 SO 问题,但是答案是模糊的和不令人满意的。

显然,一个天真的新手想要做的是直接从文件系统加载模板,而不是作为包中的资源。这是怎么做到的?

137563 次浏览

下面是 的方法: 使用 FileSystemLoader而不是 PackageLoader。我在网上找到了 给你给你的例子。假设您有一个与模板位于同一目录中的 python 文件:

./index.py
./template.html

Py 将找到模板并呈现它:

#!/usr/bin/python
import jinja2


templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "template.html"
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render()  # this is where to put args to the template renderer


print(outputText)

原来,jinja2API 文档确实有一个 讨论所有内置装载机的部分,所以没有马上注意到这一点有点尴尬。但是引言的措辞使得 PackageLoader似乎是默认的、“最简单”的方法。对于刚刚接触蟒蛇的人来说,这可能会导致一场徒劳的追逐。

一种更简单的方法是直接调用 jinj2.Template构造函数并使用 open加载文件:

from jinja2 import Template
with open('template.html.jinja2') as file_:
template = Template(file_.read())
template.render(name='John')

这里有一句话:

from jinja2 import Template


with open('template_file.j2') as f:
template = Template(f.read())

然后您可以在另一行中呈现模板,或者在一行中呈现所有模板:

with open('template_file.j2') as f:
rendered = Template(f.read()).render(var="TEXT")

如果使用 Python 3.4 + 和 Jinja2-v2.11 + ,我们可以结合 Python 的 pathlib 和 Filessystem 来简化流程

from pathlib import Path
...


p = Path(__file__).parent.parent / 'templates' # sample relative path
env = Environment(
loader=FileSystemLoader(Path(p)))
template = env.get_template('your_file.jinja2')

我不喜欢直接使用 Template(file),因为金贾的模板继承处理可能不太好用。

Pathlib 支持只在金贾的最新版本中增加-v2.11 +

from jinja2 import Environment, select_autoescape, FileSystemLoader


env = Environment(loader=FileSystemLoader(
searchpath=folder_contain_list_html), autoescape=select_autoescape(['html', 'xml']))


template = env.get_template('file_name_detail_template')


body_html = template.render(**args)


send_email(body_html)