API¶
本文档描述了 Jinja 的 API,而不是模板语言(有关模板语言,请参阅 模板设计器文档)。对于实现应用程序模板界面的用户,而不是创建 Jinja 模板的用户,它将作为参考最有用。
基础知识¶
Jinja 使用一个称为模板的中心对象 Environment
。此类的实例用于存储配置和全局对象,并用于从文件系统或其他位置加载模板。即使你使用 Template
类的构造函数从字符串创建模板,也会为你自动创建一个环境,尽管是共享环境。
大多数应用程序将在应用程序初始化时创建一个 Environment
对象,并使用它加载模板。但在某些情况下,如果使用不同的配置,则将多个环境并排放置很有用。
为应用程序配置 Jinja 以加载模板的最简单方法是使用 PackageLoader
。
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
loader=PackageLoader("yourapp"),
autoescape=select_autoescape()
)
这将创建一个模板环境,其中包含一个加载器,该加载器在 templates
文件夹中查找模板,该文件夹位于 yourapp
Python 包内(或位于 yourapp.py
Python 模块旁边)。它还为 HTML 文件启用了自动转义。此加载器仅要求 yourapp
可导入,它会为你找出该文件夹的绝对路径。
有不同的加载器可用于以其他方式或从其他位置加载模板。它们列在下面的 加载器 部分中。如果你想从更适合你的项目的源加载模板,你还可以自己编写加载器。
要从此环境加载模板,请调用 get_template()
方法,该方法返回已加载的 Template
。
template = env.get_template("mytemplate.html")
要使用一些变量渲染它,请调用 render()
方法。
print(template.render(the="variables", go="here"))
使用模板加载器而不是将字符串传递给 Template
或 Environment.from_string()
有多个优点。除了更容易使用之外,它还支持模板继承。
关于自动转义的说明
在未来版本的 Jinja 中,我们可能会出于安全原因默认启用自动转义。因此,我们建议你现在显式配置自动转义,而不是依赖默认设置。
高级 API¶
高级 API 是你将在应用程序中用于加载和渲染 Jinja 模板的 API。另一方面,低级 API 仅在你想要深入了解 Jinja 或 开发扩展 时才有用。
- 类 jinja2.Environment([options])¶
Jinja 的核心组件是
Environment
。它包含重要的共享变量,如配置、过滤器、测试、全局变量等。如果这些类实例不共享,并且到目前为止尚未加载任何模板,则可以对其进行修改。在加载第一个模板后对环境进行修改会导致令人惊讶的效果和未定义的行为。以下是可能的初始化参数
block_start_string
标记块开始的字符串。默认为
'{%'
。block_end_string
标记块结束的字符串。默认为
'%}'
。variable_start_string
标记打印语句开始的字符串。默认为
'{{'
。variable_end_string
标记打印语句结束的字符串。默认为
'}}'
。comment_start_string
标记注释开始的字符串。默认为
'{#'
。comment_end_string
标记注释结束的字符串。默认为
'#}'
。line_statement_prefix
如果给定且为字符串,则将其用作基于行的语句的前缀。另请参阅 行语句。
line_comment_prefix
如果给定且为字符串,则将其用作基于行的注释的前缀。另请参阅 行语句。
变更日志
在 2.2 版中添加。
trim_blocks
如果将其设置为
True
,则删除块后的第一个换行符(块,而不是变量标记!)。默认为False
。lstrip_blocks
如果将其设置为
True
,则从行到块的开头去除前导空格和制表符。默认为False
。newline_sequence
开始新行的序列。必须是
'\r'
、'\n'
或'\r\n'
之一。默认值为'\n'
,这是 Linux 和 OS X 系统以及 Web 应用程序的有用默认值。keep_trailing_newline
呈现模板时保留尾随换行符。默认值为
False
,这会导致从模板末尾删除一个(如果存在)换行符。变更日志
在版本 2.7 中添加。
extensions
要使用的 Jinja 扩展列表。这可以是字符串形式的导入路径或扩展类。有关更多信息,请参阅 扩展文档。
optimized
是否应启用优化器?默认值为
True
。undefined
Undefined
或其子类,用于表示模板中未定义的值。finalize
一个可调用的函数,可用于在输出变量表达式结果之前对其进行处理。例如,可以在这里将
None
隐式转换为一个空字符串。autoescape
如果设置为
True
,则默认启用 XML/HTML 自动转义功能。有关自动转义的更多详细信息,请参阅Markup
。从 Jinja 2.4 开始,这也可以是一个可调用的函数,它将传递模板名称,并根据是否应默认启用自动转义返回True
或False
。变更日志
在版本 2.4 中更改:
autoescape
现在可以是一个函数loader
此环境的模板加载器。
cache_size
缓存的大小。默认情况下,此值为
400
,这意味着如果加载的模板超过 400 个,则加载器将清除最近最少使用的模板。如果缓存大小设置为0
,则始终重新编译模板;如果缓存大小为-1
,则不会清除缓存。变更日志
在版本 2.8 中更改: 缓存大小已从较低的 50 增加到 400。
auto_reload
一些加载器从模板源可能发生更改的位置(即:文件系统或数据库)加载模板。如果
auto_reload
设置为True
(默认值),则每次请求模板时,加载器都会检查源是否已更改,如果已更改,它将重新加载模板。为了获得更高的性能,可以禁用此功能。字节码缓存
如果设置为字节码缓存对象,此对象将为内部 Jinja 字节码提供缓存,以便在模板未更改时不必对其进行解析。
有关更多信息,请参见 字节码缓存。
enable_async
如果设置为 true,这将启用异步模板执行,从而允许使用异步函数和生成器。
- 参数:
block_start_string (str)
block_end_string (str)
variable_start_string (str)
variable_end_string (str)
comment_start_string (str)
comment_end_string (str)
line_statement_prefix (str | None)
line_comment_prefix (str | None)
trim_blocks (bool)
lstrip_blocks (bool)
newline_sequence (te.Literal['\n', '\r\n', '\r'])
keep_trailing_newline (bool)
optimized (bool)
loader (基本加载器 | 无)
cache_size (整数)
auto_reload (布尔)
bytecode_cache (字节码缓存 | 无)
enable_async (布尔)
如果使用
模板
构造函数创建了模板,则会自动创建一个环境。这些环境被创建为共享环境,这意味着多个模板可能具有相同的匿名环境。对于所有共享环境,此属性为真
,否则为假
。
- 沙盒¶
如果环境是沙盒环境,则此属性为
True
。有关沙盒模式,请参阅SandboxedEnvironment
的文档。
- code_generator_class¶
用于生成代码的类。在大多数情况下不应更改此类,除非你需要修改模板编译成的 Python 代码。
- overlay([options])¶
创建一个新的覆盖环境,它与当前环境共享所有数据,但缓存和覆盖的属性除外。对于覆盖环境,无法移除扩展。覆盖环境会自动获取其链接到的环境的所有扩展以及可选的额外扩展。
在初始环境完全设置好之后,应创建覆盖。并非所有属性都真正链接,有些只是被复制过来,因此对原始环境的修改可能不会显现出来。
3.1.2 版中已更改: 添加了
newline_sequence
、keep_trailing_newline
和enable_async
参数以匹配__init__
。- 参数:
block_start_string (str)
block_end_string (str)
variable_start_string (str)
variable_end_string (str)
comment_start_string (str)
comment_end_string (str)
line_statement_prefix (str | None)
line_comment_prefix (str | None)
trim_blocks (bool)
lstrip_blocks (bool)
newline_sequence (te.Literal['\n', '\r\n', '\r'])
keep_trailing_newline (bool)
optimized (bool)
loader (基本加载器 | 无)
cache_size (整数)
auto_reload (布尔)
bytecode_cache (字节码缓存 | 无)
enable_async (布尔)
- 返回类型:
- undefined([hint, obj, name, exc])¶
为
name
创建一个新的Undefined
对象。这对于某些操作可能返回未定义对象的过滤器或函数非常有用。除了hint
之外,所有参数都应作为关键字参数提供,以提高可读性。如果提供了hint
,则将其用作异常的错误消息,否则将从obj
和name
自动生成错误消息。如果对生成的未定义对象执行未定义对象不允许的操作,则会引发作为exc
提供的异常。默认异常是UndefinedError
。如果提供了hint
,则可以省略name
。创建未定义对象的最常见方法是仅提供一个名称
return environment.undefined(name='some_name')
这意味着名称
some_name
未定义。如果名称来自对象的属性,则可以向未定义对象告知持有者对象以改善错误消息if not hasattr(obj, 'attr'): return environment.undefined(obj=obj, name='attr')
对于更复杂的示例,您可以提供提示。例如,
first()
过滤器会以这种方式创建一个未定义对象return environment.undefined('no first item, sequence was empty')
如果已知
name
或obj
(例如,因为访问了属性),则应将其传递给未定义对象,即使提供了自定义hint
。这使未定义对象能够增强错误消息。
- add_extension(extension)¶
在创建环境后添加扩展。
变更日志
在 2.5 版本中添加。
- extend(**attributes)¶
如果环境实例中不存在这些项,则将这些项添加到环境实例中。这由扩展用于注册回调和配置值,而不会破坏继承。
- 参数:
attributes (Any)
- 返回类型:
无
- compile_expression(source, undefined_to_none=True)¶
一个方便的帮助器方法,它返回一个可接受关键字参数的可调用对象,这些关键字参数显示为表达式中的变量。如果调用它,它将返回表达式的结果。
如果应用程序希望在模板“配置文件”或类似情况下使用与 Jinja 相同的规则,这将非常有用。
示例用法
>>> env = Environment() >>> expr = env.compile_expression('foo == 42') >>> expr(foo=23) False >>> expr(foo=42) True
默认情况下,如果表达式返回未定义的值,则返回值将转换为
None
。可以通过将undefined_to_none
设置为False
来更改此设置。>>> env.compile_expression('var')() is None True >>> env.compile_expression('var', undefined_to_none=False)() Undefined
变更日志
在 2.1 版本中添加。
- compile_templates(target, extensions=None, filter_func=None, zip='deflated', log_function=None, ignore_errors=True)¶
查找加载器可以找到的所有模板,编译它们并将其存储在
target
中。如果zip
为None
,则模板将存储在目录中,而不是存储在 zip 文件中。默认情况下,使用 deflate zip 算法。要切换到存储算法,可以将zip
设置为'stored'
。extensions
和filter_func
传递给list_templates()
。返回的每个模板都将编译到目标文件夹或 zip 文件中。默认情况下,忽略模板编译错误。如果提供了日志函数,则会记录错误。如果你希望模板语法错误中止编译,你可以将
ignore_errors
设置为False
,你将在语法错误上得到一个异常。变更日志
在版本 2.4 中添加。
- list_templates(extensions=None, filter_func=None)¶
返回此环境的模板列表。这要求加载器支持加载器的
list_templates()
方法。如果模板文件夹中除了实际模板之外还有其他文件,则可以过滤返回的列表。有两种方法:要么将
extensions
设置为模板的文件扩展名列表,要么可以提供一个filter_func
,它是一个可调用对象,它传递一个模板名称,如果它应该出现在结果列表中,则应返回True
。如果加载器不支持这一点,则会引发
TypeError
。变更日志
在版本 2.4 中添加。
- join_path(template, parent)¶
将模板与父级连接。默认情况下,所有查找都相对于加载器根目录,因此此方法返回未更改的
template
参数,但如果路径应相对于父模板,则可以使用此函数来计算实际模板名称。子类可以覆盖此方法并在此处实现模板路径连接。
- get_template(name, parent=None, globals=None)¶
使用
loader
按名称加载模板,并返回Template
。如果模板不存在,则会引发TemplateNotFound
异常。- 参数:
name (str | Template) – 要加载的模板的名称。从文件系统加载模板时,即使在 Windows 上,也使用 “/” 作为路径分隔符。
parent (str | None) – 导入此模板的父模板的名称。
join_path()
可用于实现此名称转换。globals (MutableMapping[str, Any] | None) – 使用这些额外变量扩展环境
globals
,以便此模板的所有渲染均可用。如果已加载并缓存模板,则其全局变量将使用任何新项目进行更新。
- 返回类型:
变更日志
在 3.0 版中更改: 如果从缓存加载模板,则
globals
将更新模板的全局变量,而不是忽略新值。在 2.4 版中更改: 如果
name
是Template
对象,则返回该对象,且保持不变。
- select_template(names, parent=None, globals=None)¶
与
get_template()
类似,但尝试加载多个名称。如果无法加载任何名称,则会引发TemplatesNotFound
异常。- 参数:
parent (str | None) – 导入此模板的父模板的名称。
join_path()
可用于实现此名称转换。globals (MutableMapping[str, Any] | None) – 使用这些额外变量扩展环境
globals
,以便此模板的所有渲染均可用。如果已加载并缓存模板,则其全局变量将使用任何新项目进行更新。
- 返回类型:
变更日志
在 3.0 版中更改: 如果从缓存加载模板,则
globals
将更新模板的全局变量,而不是忽略新值。在 2.11 版中更改: 如果
names
是Undefined
,则会引发UndefinedError
,而不是引发TemplatesNotFound
。如果没有找到任何模板,且names
包含Undefined
,则消息会更有用。在 2.4 版本中更改: 如果
names
包含Template
对象,则按原样返回。在 2.3 版本中添加。
- get_or_select_template(template_name_or_list, parent=None, globals=None)¶
如果给定可迭代的模板名称,则使用
select_template()
,如果给定一个名称,则使用get_template()
。变更日志
在 2.3 版本中添加。
- from_string(source, globals=None, template_class=None)¶
从源字符串加载模板,而不使用
loader
。
- class jinja2.Template(source, block_start_string=BLOCK_START_STRING, block_end_string=BLOCK_END_STRING, variable_start_string=VARIABLE_START_STRING, variable_end_string=VARIABLE_END_STRING, comment_start_string=COMMENT_START_STRING, comment_end_string=COMMENT_END_STRING, line_statement_prefix=LINE_STATEMENT_PREFIX, line_comment_prefix=LINE_COMMENT_PREFIX, trim_blocks=TRIM_BLOCKS, lstrip_blocks=LSTRIP_BLOCKS, newline_sequence=NEWLINE_SEQUENCE, keep_trailing_newline=KEEP_TRAILING_NEWLINE, extensions=(), optimized=True, undefined=Undefined, finalize=None, autoescape=False, enable_async=False)¶
可呈现的已编译模板。
使用
Environment
上的方法创建或加载模板。该环境用于配置模板的编译和行为方式。也可以直接创建模板对象。通常不建议这样做。构造函数采用与
Environment
相同的大部分参数。使用相同环境参数创建的所有模板在幕后共享相同的临时Environment
实例。模板对象应被视为不可变的。不支持对该对象进行修改。
- 参数:
block_start_string (str)
block_end_string (str)
variable_start_string (str)
variable_end_string (str)
comment_start_string (str)
comment_end_string (str)
line_statement_prefix (str | None)
line_comment_prefix (str | None)
trim_blocks (bool)
lstrip_blocks (bool)
newline_sequence (te.Literal['\n', '\r\n', '\r'])
keep_trailing_newline (bool)
optimized (bool)
enable_async (布尔)
- 返回类型:
- globals¶
一个变量字典,每次呈现模板时都可用,无需在呈现期间传递它们。不应修改此字典,因为根据模板的加载方式,它可能会与环境和其他模板共享。
默认为
Environment.globals
,除非将额外值传递给Environment.get_template()
。全局变量仅适用于模板的每次呈现都通用的数据。应将特定数据传递给
render()
。请参阅 全局命名空间。
- name¶
模板的加载名称。如果模板是从字符串加载的,则为
None
。
- filename¶
如果模板是从文件系统加载的,则为其文件名。否则为
None
。
- render([context])¶
此方法接受与
dict
构造函数相同的参数:一个字典、一个字典子类或一些关键字参数。如果不提供参数,则上下文将为空。这两个调用执行相同操作template.render(knights='that say nih') template.render({'knights': 'that say nih'})
这将返回呈现的模板,格式为字符串。
- generate([context])¶
对于非常大的模板,不一次性呈现整个模板并逐个评估每个语句并逐个生成片段可能很有用。此方法基本上执行此操作,并返回一个生成器,该生成器将一个接一个地生成字符串形式的项。
它接受与
render()
相同的参数。
- stream([context])¶
与
generate()
完全相同,但返回TemplateStream
。- 参数:
- 返回类型:
- async render_async([context])¶
此方法类似于
render()
,但返回一个协程,当等待时返回整个渲染后的模板字符串。这需要启用 async 特性。示例用法
await template.render_async(knights='that say nih; asynchronously')
- async generate_async([context])¶
generate()
的 async 版本。工作方式非常类似,但返回一个 async 迭代器。- 参数:
- 返回类型:
- make_module(vars=None, shared=False, locals=None)¶
此方法在不带参数调用时与
module
属性类似,但它将在每次调用时评估模板,而不是缓存它。还可以提供一个 dict,然后将其用作上下文。参数与new_context()
方法的参数相同。
- property module: TemplateModule¶
模板作为模块。这用于模板运行时的导入,但如果希望从 Python 层访问导出的模板变量,它也很有用
>>> t = Template('{% macro foo() %}42{% endmacro %}23') >>> str(t.module) '23' >>> t.module.foo() == u'42' True
如果启用了异步模式,则此属性不可用。
- class jinja2.environment.TemplateStream¶
模板流的工作方式与普通 python 生成器非常相似,但它可以缓冲多个项目以减少总迭代次数。默认情况下,输出是不缓冲的,这意味着对于模板中的每个非缓冲指令,都会生成一个字符串。
如果使用缓冲区大小为 5 启用缓冲,则五个项目将合并到一个新字符串中。这主要在通过 WSGI 将大型模板流式传输到客户端时有用,该客户端在每次迭代后都会刷新。
- dump(fp, encoding=None, errors='strict')¶
将完整流转储到文件或类文件对象中。默认情况下,字符串会被写入,如果你想在写入前进行编码,请指定一个
encoding
。示例用法
Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
- disable_buffering()¶
禁用输出缓冲。
- 返回类型:
无
自动转义¶
变更日志
在 2.4 版本中已更改。
Jinja 现在带有自动转义支持。从 Jinja 2.9 开始,自动转义扩展已被移除并内置。但是,自动转义尚未默认启用,尽管这很可能会在未来发生改变。建议为自动转义配置一个合理的默认值。这使得可以逐个模板启用和禁用自动转义(例如 HTML 与文本)。
- jinja2.select_autoescape(enabled_extensions=('html', 'htm', 'xml'), disabled_extensions=(), default_for_string=True, default=False)¶
根据模板的文件名智能设置自动转义的初始值。如果你不想自己编写自定义函数,这是配置自动转义的推荐方法。
如果你想为所有由字符串创建的模板或所有扩展名为
.html
和.xml
的模板启用它from jinja2 import Environment, select_autoescape env = Environment(autoescape=select_autoescape( enabled_extensions=('html', 'xml'), default_for_string=True, ))
示例配置,可在所有时间启用,除非模板以
.txt
结尾from jinja2 import Environment, select_autoescape env = Environment(autoescape=select_autoescape( disabled_extensions=('txt',), default_for_string=True, default=True, ))
enabled_extensions
是应为其启用自动转义的所有扩展的迭代对象。同样,disabled_extensions
是应为其禁用自动转义的所有模板的列表。如果从字符串加载模板,则使用default_for_string
中的默认值。如果没有任何匹配项,则自动转义的初始值将设置为default
的值。出于安全原因,此函数以不区分大小写的方式运行。
变更日志
在版本 2.9 中添加。
- 参数:
enabled_extensions (Collection[str])
disabled_extensions (Collection[str])
default_for_string (bool)
default (bool)
- 返回类型:
这是一个推荐的设置,它为以 '.html'
、'.htm'
和 '.xml'
结尾的模板启用自动转义,并为所有其他扩展默认禁用自动转义。你可以为此使用 select_autoescape()
函数
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
loader=PackageLoader('mypackage'))
函数 select_autoescape()
返回一个大致这样工作的函数
def autoescape(template_name):
if template_name is None:
return False
if template_name.endswith(('.html', '.htm', '.xml'))
在实现一个猜测自动转义函数时,确保你也接受 None
作为有效的模板名称。这将在从字符串生成模板时传递。你应该始终将自动转义配置为默认值,因为未来可能会更改。
在模板中,可以使用 autoescape
块来临时更改行为(请参阅 自动转义覆盖)。
标识符注释¶
Jinja 使用 Python 命名规则。有效的标识符可以是 Python 接受的任何字符组合。
过滤器和测试在单独的命名空间中查找,并且标识符语法略有修改。过滤器和测试可能包含点,按主题对过滤器和测试进行分组。例如,将函数添加到过滤器字典并调用它 to.str
是完全有效的。过滤器和测试标识符的正则表达式为 [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*
。
未定义类型¶
这些类可以用作未定义类型。 Environment
构造函数采用一个 undefined
参数,它可以是那些类之一或 Undefined
的自定义子类。每当模板引擎无法查找名称或访问属性时,都会创建一个这样的对象并返回。然后允许对未定义值执行某些操作,而其他操作则失败。
最接近常规 Python 行为的是 StrictUndefined
,它禁止除测试它是否为未定义对象之外的所有操作。
- class jinja2.Undefined¶
默认未定义类型。此未定义类型可以打印和迭代,但其他任何访问都将引发
UndefinedError
>>> foo = Undefined(name='foo') >>> str(foo) '' >>> not foo True >>> foo + 42 Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined
- 参数:
提示 (str | None)
obj (Any)
名称 (str | None)
exc (Type[TemplateRuntimeError])
- _undefined_hint¶
要么是
None
,要么是包含未定义对象错误消息的字符串。
- _undefined_obj¶
要么是
None
,要么是导致创建未定义对象的拥有者对象(例如,因为属性不存在)。
- _undefined_name¶
未定义变量/属性的名称,或者如果不存在此类信息,则只是
None
。
- _undefined_exception¶
未定义对象想要引发的异常。这通常是
UndefinedError
或SecurityError
之一。
- _fail_with_undefined_error(\*args, \**kwargs)¶
当使用任何参数调用此方法时,此方法会引发
_undefined_exception
,其中包含从存储在未定义对象上的未定义提示中生成错误消息。
- class jinja2.ChainableUndefined¶
一个可链接的未定义,其中
__getattr__
和__getitem__
都返回自身,而不是引发UndefinedError
。>>> foo = ChainableUndefined(name='foo') >>> str(foo.bar['baz']) '' >>> foo.bar['baz'] + 42 Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined
变更日志
在 2.11.0 版本中添加。
- 参数:
提示 (str | None)
obj (Any)
名称 (str | None)
exc (Type[TemplateRuntimeError])
- class jinja2.DebugUndefined¶
一个在打印时返回调试信息的未定义。
>>> foo = DebugUndefined(name='foo') >>> str(foo) '{{ foo }}' >>> not foo True >>> foo + 42 Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined
- 参数:
提示 (str | None)
obj (Any)
名称 (str | None)
exc (Type[TemplateRuntimeError])
- class jinja2.StrictUndefined¶
一个在打印和迭代以及布尔测试和各种比较中都会发出警告的未定义。换句话说:除了使用
defined
测试检查它是否已定义,你无法对它做任何事情。>>> foo = StrictUndefined(name='foo') >>> str(foo) Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined >>> not foo Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined >>> foo + 42 Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined
- 参数:
提示 (str | None)
obj (Any)
名称 (str | None)
exc (Type[TemplateRuntimeError])
还有一个工厂函数,可以装饰未定义对象以在失败时实现日志记录
- jinja2.make_logging_undefined(logger=None, base=Undefined)¶
给定一个记录器对象,这将返回一个新的未定义类,该类将记录某些失败。它将记录迭代和打印。如果没有提供记录器,则会创建一个默认记录器。
示例
logger = logging.getLogger(__name__) LoggingUndefined = make_logging_undefined( logger=logger, base=Undefined )
变更日志
在 2.8 版本中添加。
通过调用 undefined
创建未定义对象。
实现
Undefined
是通过覆盖特殊 __underscore__
方法实现的。例如,默认 Undefined
类实现 __str__
以返回一个空字符串,而 __int__
和其他则会引发异常。要通过返回 0
来允许转换为 int,你可以实现自己的子类。
class NullUndefined(Undefined):
def __int__(self):
return 0
def __float__(self):
return 0.0
要禁止方法,请重写它并引发 _undefined_exception
。由于这非常常见,因此有辅助方法 _fail_with_undefined_error()
,它会引发带有正确信息的错误。这是一个类,其工作方式与常规 Undefined
相同,但在迭代时会失败
class NonIterableUndefined(Undefined):
def __iter__(self):
self._fail_with_undefined_error()
上下文¶
- class jinja2.runtime.Context¶
模板上下文保存模板的变量。它存储传递给模板的值,还存储模板导出的名称。创建实例既不受支持也不实用,因为它在模板评估的不同阶段自动创建,不应手动创建。
上下文是不可变的。对
parent
的修改不得发生,而对vars
的修改仅允许来自生成的模板代码。标记为pass_context()
的模板过滤器和全局函数将活动上下文作为第一个参数传递,并且允许只读访问上下文。模板上下文支持只读字典操作(
get
、keys
、values
、items
、iterkeys
、itervalues
、iteritems
、__getitem__
、__contains__
)。此外,还有一个resolve()
方法,它不会因KeyError
而失败,而是返回一个Undefined
对象以表示缺失的变量。- 参数:
- parent¶
模板查找的只读全局变量的字典。这些变量可以来自另一个
Context
、Environment.globals
或Template.globals
,或者指向通过将全局变量与传递给渲染函数的变量组合而创建的字典。它不得被更改。
- environment¶
加载模板的环境。
- exported_vars¶
此集合包含模板导出的所有名称。名称的值位于
vars
字典中。为了获取导出变量的副本作为字典,可以使用get_exported()
。
- name¶
拥有此上下文的模板的加载名称。
- blocks¶
一个字典,其中包含模板中块的当前映射。此字典中的键是块的名称,而值是已注册块的列表。每个列表中的最后一个项目是当前活动块(继承链中的最新块)。
- call(callable, \*args, \**kwargs)¶
使用提供的参数和关键字参数调用可调用对象,但如果可调用对象具有
pass_context()
或pass_environment()
,则将活动上下文或环境注入为第一个参数。
- get(key, default=None)¶
按名称查找变量,或在找不到键时返回默认值。
- resolve(key)¶
按名称查找变量,或如果找不到 key,则返回
Undefined
对象。如果您需要添加自定义行为,请覆盖
resolve_or_missing()
,而不是此方法。各种查找函数使用该方法,而不是此方法。
上下文是不可变的,它防止修改,并且如果它以某种方式被修改,则这些更改可能不会显示出来。为了提高性能,Jinja 不使用上下文作为数据存储,仅作为主要数据源。模板未定义的变量在上下文中查找,但模板定义的变量存储在本地。
不要直接修改上下文,函数应返回一个值,该值可以分配给模板本身中的变量。
{% set comments = get_latest_comments() %}
加载器¶
加载器负责从文件系统等资源加载模板。环境会将已编译的模块保存在内存中,就像 Python 的 sys.modules
一样。然而,与 sys.modules
不同的是,此缓存默认情况下大小有限,并且模板会自动重新加载。所有加载器都是 BaseLoader
的子类。如果您想创建自己的加载器,请对 BaseLoader
进行子类化并覆盖 get_source
。
- class jinja2.BaseLoader¶
所有加载器的基类。对它进行子类化并覆盖
get_source
以实现自定义加载机制。环境提供一个get_template
方法,该方法调用加载器的load
方法以获取Template
对象。查找文件系统上模板的加载器的非常基本的示例如下所示
from jinja2 import BaseLoader, TemplateNotFound from os.path import join, exists, getmtime class MyLoader(BaseLoader): def __init__(self, path): self.path = path def get_source(self, environment, template): path = join(self.path, template) if not exists(path): raise TemplateNotFound(template) mtime = getmtime(path) with open(path) as f: source = f.read() return source, path, lambda: mtime == getmtime(path)
- get_source(environment, template)¶
获取模板源、文件名和重新加载帮助器。它传递环境和模板名称,并且必须以
(source, filename, uptodate)
的形式返回一个元组,或者如果无法找到模板,则引发TemplateNotFound
错误。返回元组的源部分必须是模板的源代码(字符串形式)。如果文件是从文件系统加载的,则文件名应该是文件系统上的文件名,否则为
None
。如果没有使用加载器扩展,则 Python 会使用文件名进行回溯。元组中的最后一个项目是
uptodate
函数。如果启用了自动重新加载,则始终调用它来检查模板是否已更改。没有传递任何参数,因此该函数必须将旧状态存储在某个地方(例如闭包中)。如果它返回False
,则将重新加载模板。
- load(environment, name, globals=None)¶
加载模板。此方法在缓存中查找模板,或通过调用
get_source()
加载模板。子类不应覆盖此方法,因为处理其他加载器集合的加载器(如PrefixLoader
或ChoiceLoader
)不会调用此方法,而是直接调用get_source
。- 参数:
environment (Environment)
name (str)
globals (MutableMapping[str, Any] | None)
- 返回类型:
以下是 Jinja 提供的内置加载器列表
- 类 jinja2.FileSystemLoader(searchpath, encoding='utf-8', followlinks=False)¶
从文件系统中的目录加载模板。
路径可以是相对路径或绝对路径。相对路径相对于当前工作目录。
loader = FileSystemLoader("templates")
可以提供路径列表。将按顺序搜索目录,在第一个匹配的模板处停止。
loader = FileSystemLoader(["/override/templates", "/default/templates"])
- 参数:
searchpath (str | os.PathLike[str] | Sequence[str | os.PathLike[str]]) – 包含模板的目录的路径或路径列表。
encoding (str) – 使用此编码从模板文件中读取文本。
followlinks (bool) – 遵循路径中的符号链接。
变更日志
在 2.8 版中更改: 添加了
followlinks
参数。
- 类 jinja2.PackageLoader(package_name, package_path='templates', encoding='utf-8')¶
从 Python 包中的目录加载模板。
- 参数:
以下示例在
project.ui
包中的pages
目录中查找模板。loader = PackageLoader("project.ui", "pages")
仅支持作为目录(标准 pip 行为)或 zip/egg 文件(不太常见)安装的包。用于内省包中数据的 Python API 过于受限,无法支持此加载器要求的其他安装方法。
对 PEP 420 命名空间包的支持有限。模板目录假定仅在一个命名空间贡献者中。不支持贡献命名空间的 Zip 文件。
变更日志
在版本 3.0 中更改:不再使用
setuptools
作为依赖项。在版本 3.0 中更改:有限的 PEP 420 命名空间包支持。
- 类 jinja2.DictLoader(映射)¶
从 Python 字典映射(将模板名称映射到模板源)加载模板。此加载器对于单元测试很有用
>>> loader = DictLoader({'index.html': 'source here'})
由于自动重新加载很少有用,因此默认情况下已禁用此功能。
- 类 jinja2.FunctionLoader(加载函数)¶
一个加载器,它传递一个执行加载的函数。该函数接收模板的名称,并且必须返回一个包含模板源的字符串、一个形式为
(源, 文件名, uptodatefunc)
的元组,或者在模板不存在的情况下返回None
。>>> def load_template(name): ... if name == 'index.html': ... return '...' ... >>> loader = FunctionLoader(load_template)
如果启用了自动重新加载,则会调用
uptodatefunc
,并且如果模板仍然是最新的,则必须返回True
。有关更多详细信息,请参阅BaseLoader.get_source()
,它具有相同的返回值。
- class jinja2.PrefixLoader(mapping, delimiter='/')¶
一个加载器,它传递一个加载器字典,其中每个加载器都绑定到一个前缀。默认情况下,前缀由一个斜杠从模板中分隔,可以通过将
delimiter
参数设置成其他内容来更改loader = PrefixLoader({ 'app1': PackageLoader('mypackage.app1'), 'app2': PackageLoader('mypackage.app2') })
通过加载
'app1/index.html'
从 app1 包中加载文件,通过加载'app2/index.html'
从第二个包中加载文件。- 参数:
mapping (Mapping[str, BaseLoader])
delimiter (str)
- class jinja2.ChoiceLoader(loaders)¶
此加载器的工作方式与
PrefixLoader
相同,只是未指定前缀。如果一个加载器找不到模板,则尝试下一个加载器。>>> loader = ChoiceLoader([ ... FileSystemLoader('/path/to/user/templates'), ... FileSystemLoader('/path/to/system/templates') ... ])
如果你想允许用户从不同位置覆盖内置模板,这很有用。
- 参数:
loaders (Sequence[BaseLoader])
- class jinja2.ModuleLoader(path)¶
此加载器从预编译模板加载模板。
示例用法
>>> loader = ChoiceLoader([ ... ModuleLoader('/path/to/compiled/templates'), ... FileSystemLoader('/path/to/templates') ... ])
可以使用
Environment.compile_templates()
预编译模板。- 参数:
path (str | os.PathLike[str] | Sequence[str | os.PathLike[str]])
字节码缓存¶
Jinja 2.1 及更高版本支持外部字节码缓存。字节码缓存可以将生成的字节码存储在文件系统或其他位置,以避免在首次使用时解析模板。
如果你有一个在第一次请求时初始化的 Web 应用程序,并且 Jinja 一次编译许多模板,从而减慢了应用程序的速度,这将特别有用。
要使用字节码缓存,请对其进行实例化并将其传递给 Environment
。
- class jinja2.BytecodeCache¶
要实现你自己的字节码缓存,你必须对这个类进行子类化,并覆盖
load_bytecode()
和dump_bytecode()
。这两个方法都传递了一个Bucket
。一个非常基本的字节码缓存,它将字节码保存在文件系统上
from os import path class MyCache(BytecodeCache): def __init__(self, directory): self.directory = directory def load_bytecode(self, bucket): filename = path.join(self.directory, bucket.key) if path.exists(filename): with open(filename, 'rb') as f: bucket.load_bytecode(f) def dump_bytecode(self, bucket): filename = path.join(self.directory, bucket.key) with open(filename, 'wb') as f: bucket.write_bytecode(f)
一个基于文件系统的字节码缓存的更高级版本是 Jinja 的一部分。
- load_bytecode(bucket)¶
子类必须覆盖此方法才能将字节码加载到存储桶中。如果它们无法在缓存中找到存储桶的代码,则它不应执行任何操作。
- 参数:
bucket (Bucket)
- 返回类型:
无
- dump_bytecode(bucket)¶
子类必须覆盖此方法才能将字节码从存储桶写回缓存。如果它无法这样做,则它不能静默失败,而必须引发异常。
- 参数:
bucket (Bucket)
- 返回类型:
无
- clear()¶
清除缓存。Jinja 不使用此方法,但应实现此方法以允许应用程序清除特定环境使用的字节码缓存。
- 返回类型:
无
- class jinja2.bccache.Bucket(environment, key, checksum)¶
存储一个模板的字节码。它由字节码缓存创建并初始化,并传递给加载函数。
存储段从缓存中获取内部校验和并使用它自动拒绝过时的缓存材料。各个字节码缓存子类不必关心缓存失效。
- 参数:
environment (Environment)
key (str)
checksum (str)
- environment¶
创建存储段的
Environment
。
- key¶
此存储段的唯一缓存键
- code¶
如果已加载字节码,否则为
None
。
- reset()¶
重置存储段(卸载字节码)。
- 返回类型:
无
内置字节码缓存
- class jinja2.FileSystemBytecodeCache(directory=None, pattern='__jinja2_%s.cache')¶
将字节码存储在文件系统上的字节码缓存。它接受两个参数:存储缓存项的目录和用于构建文件名模式字符串。
如果未指定目录,则选择默认缓存目录。在 Windows 上,使用用户的临时目录,在 UNIX 系统上,在系统临时目录中为用户创建目录。
该模式可用于在同一目录上操作多个单独的缓存。默认模式为
'__jinja2_%s.cache'
。%s
用缓存键替换。>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
此字节码缓存支持使用 clear 方法清除缓存。
- 类 jinja2.MemcachedBytecodeCache(客户端, 前缀='jinja2/bytecode/', 超时=无, 忽略 memcache 错误=真)¶
此类实现了一个字节码缓存,该缓存使用 memcache 缓存来存储信息。它不强制使用特定的 memcache 库(tummy 的 memcache 或 cmemcache),但会接受提供所需最小界面的任何类。
与此类兼容的库
(不幸的是,django 缓存界面不兼容,因为它不支持存储二进制数据,仅支持文本。但是,你可以将底层缓存客户端传递给字节码缓存,该缓存作为
django.core.cache.cache._client
提供。)传递给构造函数的客户端的最小界面如下
- 类 MinimalClientInterface¶
- 设置(键, 值[, 超时])¶
将字节码存储在缓存中。
值
是一个字符串,超时
是键的超时。如果未提供超时,则应假定默认超时或无超时,如果提供了超时,则它是一个整数,表示缓存项应存在的秒数。
- get(key)¶
返回缓存键的值。如果该项在缓存中不存在,则返回值必须为
None
。
构造函数的其他参数是所有键的前缀,该前缀在实际缓存键之前添加,以及缓存系统中字节码的超时时间。我们建议使用较高的(或无)超时时间。
此字节码缓存不支持清除缓存中已使用的项。clear 方法是无操作函数。
变更日志
在版本 2.7 中添加: 通过
ignore_memcache_errors
参数添加了对忽略 memcache 错误的支持。
异步支持¶
变更日志
在版本 2.9 中添加。
Jinja 支持 Python async
和 await
语法。对于模板设计人员而言,此支持(启用时)完全透明,模板继续保持完全相同的外观。但是,开发人员应了解实现,因为它会影响您可以使用的 API 类型。
默认情况下,异步支持处于禁用状态。启用它将导致环境在幕后编译不同的代码,以便在 asyncio 事件循环中处理异步和同步代码。这具有以下含义
已编译的代码对函数和属性使用
await
,并对async for
循环使用await
。为了支持在此上下文中同时使用异步和同步函数,在所有调用和访问周围放置了一个小包装器,与纯异步代码相比,这增加了开销。在需要时,同步方法和过滤器成为其相应异步实现的包装器。例如,
render
调用async_render
,并且|map
支持异步可迭代对象。
可等待对象可以从模板中的函数返回,并且模板中的任何函数调用都将自动等待结果。通常在 Python 中添加的 await
是隐含的。例如,你可以提供一个异步从数据库加载数据的方法,并且从模板设计者的角度来看,它可以像其他任何函数一样被调用。
策略¶
从 Jinja 2.9 开始,可以在环境中配置策略,这些策略可以轻微影响过滤器和其他模板构造的行为。它们可以通过 policies
属性进行配置。
示例
env.policies['urlize.rel'] = 'nofollow noopener'
truncate.leeway
:为
truncate
过滤器配置 leeway 默认值。leeway 在 2.9 中引入,但为了恢复与旧模板的兼容性,可以将其配置为0
以恢复旧行为。默认值为5
。urlize.rel
:一个字符串,用于定义使用
urlize
过滤器生成的链接的rel
属性的项。这些项始终被添加。默认值为noopener
。urlize.target
:如果调用中未明确定义其他目标,则为
urlize
过滤器中的链接发出的默认目标。urlize.extra_schemes
:除了默认的
http://
、https://
和mailto:
之外,识别以这些方案开头的 URL。json.dumps_function
:如果将其设置为
None
以外的值,则tojson
过滤器将使用此函数而不是默认函数进行转储。请注意,此函数应接受任意额外的参数,这些参数可能将来从过滤器中传递。目前可能传递的唯一参数是indent
。默认转储函数是json.dumps
。json.dumps_kwargs
:要传递给转储函数的关键字参数。默认值为
{'sort_keys': True}
。
ext.i18n.trimmed
:如果将其设置为
True
,i18n 扩展 的{% trans %}
块将始终统一换行符和周围的空白,就像使用了trimmed
修饰符一样。
实用工具¶
如果您向 Jinja 环境添加自定义过滤器或函数,这些帮助函数和类将非常有用。
- jinja2.pass_context(f)¶
在呈现模板时调用时,将
Context
作为装饰函数的第一个参数传递。可用于函数、过滤器和测试。
如果只需要
Context.eval_context
,请使用pass_eval_context()
。如果只需要Context.environment
,请使用pass_environment()
。变更日志
在 3.0.0 版本中添加: 替换
contextfunction
和contextfilter
。- 参数:
f (F)
- 返回类型:
F
- jinja2.pass_eval_context(f)¶
在呈现模板时调用时,将
EvalContext
作为装饰函数的第一个参数传递。请参阅 评估上下文。可用于函数、过滤器和测试。
如果只需要
EvalContext.environment
,请使用pass_environment()
。变更日志
在 3.0.0 版本中添加: 替换
evalcontextfunction
和evalcontextfilter
。- 参数:
f (F)
- 返回类型:
F
- jinja2.pass_environment(f)¶
在呈现模板时调用时,将
Environment
作为装饰函数的第一个参数传递。可用于函数、过滤器和测试。
变更日志
3.0.0 版新增: 替换
environmentfunction
和environmentfilter
。- 参数:
f (F)
- 返回类型:
F
- jinja2.clear_caches()¶
Jinja 为环境和词法分析器保留内部缓存。这些缓存用于让 Jinja 不必一直重新创建环境和词法分析器。通常情况下,您不必关心这一点,但如果您要衡量内存消耗,则可能需要清除缓存。
- 返回类型:
无
异常¶
- exception jinja2.UndefinedError(message=None)¶
如果模板尝试对
Undefined
进行操作,则会引发此错误。- 参数:
message (str | None)
- 返回类型:
无
- 异常 jinja2.TemplateNotFound(名称, 消息=无)¶
如果模板不存在,则引发。
变更日志
在版本 2.11 中更改:如果给定的名称是
Undefined
并且没有提供消息,则会引发UndefinedError
。
- 异常 jinja2.TemplatesNotFound(名称=(), 消息=无)¶
类似于
TemplateNotFound
,但如果选择了多个模板,则引发。这是TemplateNotFound
异常的子类,因此仅捕获基本异常将捕获两者。
- 异常 jinja2.TemplateSyntaxError(消息, 行号, 名称=无, 文件名=无)¶
引发以告知用户模板有问题。
- message¶
错误信息。
- lineno¶
发生错误的行号。
- name¶
模板的加载名称。
- filename¶
在文件系统编码中加载模板的文件名(很可能是 utf-8,或在 Windows 系统上为 mbcs)。
自定义过滤器¶
过滤器是 Python 函数,它们将过滤器的左侧值作为第一个参数,并生成一个新值。传递给过滤器的参数在值之后传递。
例如,过滤器 {{ 42|myfilter(23) }}
在后台被称为 myfilter(42, 23)
。
Jinja 带有一些 内置过滤器。要使用自定义过滤器,请编写一个至少带有 value
参数的函数,然后在 Environment.filters
中注册它。
这是一个格式化 datetime 对象的过滤器
def datetime_format(value, format="%H:%M %d-%m-%y"):
return value.strftime(format)
environment.filters["datetime_format"] = datetime_format
现在可以在模板中使用它
{{ article.pub_date|datetimeformat }}
{{ article.pub_date|datetimeformat("%B %Y") }}
提供了一些装饰器来告诉 Jinja 将额外信息传递给过滤器。对象作为第一个参数传递,从而使要过滤的值成为第二个参数。
pass_context()
传递当前Context
。
这是一个将换行符转换为 HTML <br>
和 <p>
标记的过滤器。它使用 eval 上下文在转义输入和标记输出为安全之前检查是否当前启用了自动转义。
import re
from jinja2 import pass_eval_context
from markupsafe import Markup, escape
@pass_eval_context
def nl2br(eval_ctx, value):
br = "<br>\n"
if eval_ctx.autoescape:
value = escape(value)
br = Markup(br)
result = "\n\n".join(
f"<p>{br.join(p.splitlines())}<\p>"
for p in re.split(r"(?:\r\n|\r(?!\n)|\n){2,}", value)
)
return Markup(result) if autoescape else result
自定义测试¶
测试是 Python 函数,它们将测试左侧的值作为第一个参数,并返回 True
或 False
。传递给测试的参数在值之后传递。
例如,测试 {{ 42 is even }}
在后台被称为 is_even(42)
。
Jinja 带有一些 内置测试。要使用自定义测试,请编写一个至少带有 value
参数的函数,然后在 Environment.tests
中注册它。
这是一个测试,用于检查一个值是否为质数
import math
def is_prime(n):
if n == 2:
return True
for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
if n % i == 0:
return False
return True
environment.tests["prime"] = is_prime
现在可以在模板中使用它
{% if value is prime %}
{{ value }} is a prime number
{% else %}
{{ value }} is not a prime number
{% endif %}
一些装饰器可用于告诉 Jinja 向测试传递额外信息。对象作为第一个参数传递,使被测试的值成为第二个参数。
pass_context()
传递当前Context
。
评估上下文¶
评估上下文(简称 eval 上下文或 eval ctx)使得在运行时激活和停用已编译的功能成为可能。
目前它仅用于启用和禁用自动转义,但扩展也可以使用它。
应在评估上下文中检查 autoescape
设置,而不是在环境中。评估上下文将具有当前模板的计算值。
代替 pass_environment
@pass_environment
def filter(env, value):
result = do_something(value)
if env.autoescape:
result = Markup(result)
return result
仅需要设置时使用 pass_eval_context
@pass_eval_context
def filter(eval_ctx, value):
result = do_something(value)
if eval_ctx.autoescape:
result = Markup(result)
return result
或者,如果还需要其他上下文行为,则使用 pass_context
@pass_context
def filter(context, value):
result = do_something(value)
if context.eval_ctx.autoescape:
result = Markup(result)
return result
评估上下文在运行时不得被修改。修改必须仅通过 nodes.EvalContextModifier
和 nodes.ScopedEvalContextModifier
从扩展进行,而不是在 eval 上下文对象本身进行。
- class jinja2.nodes.EvalContext(environment, template_name=None)¶
保存评估时间信息。自定义属性可以在扩展中附加到它。
- 参数:
environment (Environment)
template_name (str | None)
- autoescape¶
True
或False
,具体取决于自动转义是否处于活动状态。
- volatile¶
True
如果编译器无法在编译时计算一些表达式。在运行时,这始终应该是False
。
全局命名空间¶
全局命名空间存储变量和函数,这些变量和函数应该可以使用,而无需将它们传递给 Template.render()
。它们还可以用于在没有上下文的情况下导入或包含的模板。大多数应用程序应仅使用 Environment.globals
。
Environment.globals
旨在用于该环境加载的所有模板中通用的数据。 Template.globals
旨在用于该模板的所有渲染中通用的数据,并且默认为 Environment.globals
,除非它们在 Environment.get_template()
等中给出。特定于某个渲染的数据应作为上下文传递给 Template.render()
。
在任何特定渲染期间仅使用一组全局变量。如果模板 A 和 B 都具有模板全局变量,并且 B 扩展 A,那么在使用 b.render()
时,仅使用 B 的全局变量。
在加载任何模板后,不应更改环境全局变量,并且在加载模板后,不应在任何时候更改模板全局变量。在加载模板后更改全局变量将导致意外行为,因为它们可能在环境和其他模板之间共享。
底层 API¶
底层 API 公开了可用于了解某些实现细节、调试目的或高级 扩展 技术的功能。除非您确切地知道自己在做什么,否则我们不建议使用任何这些功能。
- 环境。lex(源代码, 名称=无, 文件名=无)¶
对给定的源代码进行词法分析,并返回一个生成器,以元组的形式生成令牌,格式为
(行号, 令牌类型, 值)
。这对于 扩展开发 和调试模板很有用。这不会执行预处理。如果您希望应用扩展的预处理,则必须通过
preprocess()
方法过滤源代码。
- 环境。parse(源代码, 名称=无, 文件名=无)¶
解析源代码并返回抽象语法树。编译器使用此节点树将模板转换为可执行源代码或字节码。这对于调试或从模板中提取信息很有用。
如果您正在 开发 Jinja 扩展,这将为您提供所生成节点树的良好概述。
- Template.new_context(vars=None, shared=False, locals=None)¶
为该模板创建一个新的
Context
。提供的变量将传递给模板。默认情况下,全局变量将添加到上下文中。如果将共享设置为True
,则数据将按原样传递到上下文中,而无需添加全局变量。locals
可以是用于内部使用的局部变量的字典。
- Template.root_render_func(context)¶
这是低级渲染函数。它传递了一个
Context
,该Context
必须通过同一模板或兼容模板的new_context()
创建。此渲染函数由编译器从模板代码生成,并返回一个生成字符串的生成器。如果模板代码中发生异常,模板引擎将不会重写异常,而是传递原始异常。事实上,此函数只能在
render()
/generate()
/stream()
调用中调用。
- Template.blocks¶
块渲染函数的字典。这些函数的每个函数的工作方式与
root_render_func()
完全相同,并且具有相同的限制。
- Template.is_up_to_date¶
如果存在更新版本的模板,则此属性为
False
,否则为True
。
注意
底层 API 非常脆弱。未来的 Jinja 版本会尝试不以向后不兼容的方式对其进行更改,但 Jinja 核心中的修改可能会显现出来。例如,如果 Jinja 在以后的版本中引入了一个新的 AST 节点,该节点可能会由 parse()
返回。
元 API¶
变更日志
在 2.2 版中添加。
元 API 返回有关抽象语法树的一些信息,这些信息可以帮助应用程序实现更高级的模板概念。元 API 的所有函数都对 Environment.parse()
方法返回的抽象语法树进行操作。
- jinja2.meta.find_undeclared_variables(ast)¶
返回 AST 中所有变量的集合,这些变量将在运行时从上下文中查找。由于在编译时不知道将使用哪些变量(取决于运行时执行的路径),因此将返回所有变量。
>>> from jinja2 import Environment, meta >>> env = Environment() >>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}') >>> meta.find_undeclared_variables(ast) == {'bar'} True
实现
在内部,代码生成器用于查找未声明的变量。这一点很重要,因为代码生成器可能会在编译期间引发
TemplateAssertionError
,事实上,此函数当前也可以引发该异常。
- jinja2.meta.find_referenced_templates(ast)¶
从 AST 中查找所有引用的模板。这将返回一个迭代器,遍历所有硬编码的模板扩展、包含和导入。如果使用了动态继承或包含,将产生
None
。>>> from jinja2 import Environment, meta >>> env = Environment() >>> ast = env.parse('{% extends "layout.html" %}{% include helper %}') >>> list(meta.find_referenced_templates(ast)) ['layout.html', None]
此函数对于依赖项跟踪很有用。例如,如果要在布局模板更改后重建网站的某些部分。