API — Jinja 文档
应用程序接口
本文档描述的是 Jinja 的 API 而不是模板语言(为此,请参阅 模板设计器文档 )。 对于那些实现应用程序模板接口的人而不是那些创建 Jinja 模板的人来说,这将是最有用的参考。
基本
Jinja 使用称为模板 Environment 的中心对象。 此类的实例用于存储配置和全局对象,并用于从文件系统或其他位置加载模板。 即使您使用 Template 类的构造函数从字符串创建模板,也会自动为您创建一个环境,尽管是共享环境。
大多数应用程序会在应用程序初始化时创建一个 Environment 对象并使用它来加载模板。 但是,在某些情况下,如果使用不同的配置,同时拥有多个环境会很有用。
配置 Jinja 以加载应用程序模板的最简单方法是使用 PackageLoader。
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
loader=PackageLoader("yourapp"),
autoescape=select_autoescape()
)
这将创建一个带有加载程序的模板环境,该加载程序在 yourapp
Python 包(或 yourapp.py
Python 模块旁边)内的 templates
文件夹中查找模板。 它还为 HTML 文件启用自动转义。 这个加载器只需要yourapp
是可导入的,它会为你找出文件夹的绝对路径。
不同的加载器可用于以其他方式或从其他位置加载模板。 它们列在下面的 Loaders 部分中。 如果您想从更专门用于您的项目的源加载模板,您也可以编写自己的模板。
要从此环境加载模板,请调用 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 或 开发扩展 时才有用。
- class jinja2.Environment([options])
Jinja 的核心组件是 Environment。 它包含重要的共享变量,如配置、过滤器、测试、全局变量等。 如果此类的实例未共享且到目前为止未加载模板,则可能会修改它们。 加载第一个模板后对环境的修改将导致令人惊讶的效果和未定义的行为。
以下是可能的初始化参数:
- block_start_string
标记块开始的字符串。 默认为
'{%'
。- block_end_string
标记块结束的字符串。 默认为
'%}'
。- 变量起始字符串
标记打印语句开始的字符串。 默认为
'{{'
。- variable_end_string
标记打印语句结束的字符串。 默认为
'}}'
。- comment_start_string
标记注释开头的字符串。 默认为
'{#'
。- comment_end_string
标记注释结束的字符串。 默认为
'#}'
。- line_statement_prefix
如果给定和字符串,这将用作基于行的语句的前缀。 另见 行语句 。
- line_comment_prefix
如果给定和字符串,这将用作基于行的注释的前缀。 另见 行语句 。
2.2 版中的新功能。
- 修剪块
如果将其设置为
True
删除块后的第一个换行符(块,而不是变量标签!)。 默认为 False。- lstrip_blocks
如果设置为
True
前导空格和制表符将从行首剥离到块。 默认为 False。- 换行序列
开始换行的序列。 必须是
'\r'
、'\n'
或'\r\n'
之一。 默认值为'\n'
,这是 Linux 和 OS X 系统以及 Web 应用程序的有用默认值。- keep_trailing_newline
渲染模板时保留尾随换行符。 默认值为
False
,这会导致从模板末尾删除单个换行符(如果存在)。2.7 版中的新功能。
- 扩展
要使用的 Jinja 扩展列表。 这可以是作为字符串或扩展类的导入路径。 有关更多信息,请查看 扩展文档 。
- 优化
应该启用优化器吗? 默认值为
True
。- 不明确的
Undefined 或其子类,用于表示模板中的未定义值。
- 敲定
可用于在输出之前处理变量表达式的结果的可调用对象。 例如,可以在此处将
None
隐式转换为空字符串。- 自动逃生
如果设置为
True
,则默认启用 XML/HTML 自动转义功能。 有关自动转义的更多详细信息,请参阅Markup
。 从 Jinja 2.4 开始,这也可以是传递模板名称的可调用对象,并且必须返回True
或False
取决于默认情况下应启用自动转义。2.4 版更改:autoescape 现在可以是一个函数
- 装载机
此环境的模板加载器。
- 缓存大小
缓存的大小。 默认情况下,这是
400
,这意味着如果加载了 400 个以上的模板,加载程序将清除最近最少使用的模板。 如果缓存大小设置为0
模板会一直重新编译,如果缓存大小设置为-1
则不会清除缓存。2.8 版本变更:缓存大小从原来的 50 增加到 400。
- 自动重新加载
一些加载器从模板源可能改变的位置加载模板(即:文件系统或数据库)。 如果每次请求模板时将
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]) –
line_comment_prefix (可选[str]) –
trim_blocks (bool) –
lstrip_blocks (bool) –
'newline_sequence (te.Literal['\n',' ]\r\n', \r']) –
keep_trailing_newline (bool) –
扩展(序列[联合[str, 类型[扩展]]]) –
优化 (bool) –
undefined (Type[jinja2.runtime.Undefined]) –
finalize (可选[Callable[[...[ X90X]],任何]]) –
autoescape (Union[bool,Callable[ [可选[str]][X1717X] X184X]bool]]) –
loader (可选[BaseLoader]) –
cache_size (int) –
auto_reload (bool) –
bytecode_cache (可选[BytecodeCache]) –
enable_async (bool) –
- shared
如果模板是使用 Template 构造函数创建的,则会自动创建环境。 这些环境被创建为共享环境,这意味着多个模板可能具有相同的匿名环境。 对于所有共享环境,此属性为 True,否则为 False。
- sandboxed
如果环境被沙箱化,则此属性为 True。 对于沙盒模式,请查看 SandboxedEnvironment 的文档。
- policies
带有 策略 的字典。 这些可以重新配置以更改运行时行为或某些模板功能。 通常这些都是安全相关的。
- code_generator_class
用于代码生成的类。 在大多数情况下,这不应更改,除非您需要修改模板编译为的 Python 代码。
- context_class
用于模板的上下文。 在大多数情况下,这不应更改,除非您需要修改模板变量处理方式的内部结构。 有关详细信息,请参阅 上下文 。
- overlay([options])
创建一个新的覆盖环境,该环境与当前环境共享除缓存和覆盖属性之外的所有数据。 无法为覆盖环境删除扩展。 覆盖的环境会自动获取它所链接的环境的所有扩展以及可选的额外扩展。
创建覆盖应该在初始环境完全设置之后发生。 并非所有属性都真正链接在一起,有些只是复制过来,因此对原始环境的修改可能无法体现出来。
- 参数
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]) –
line_comment_prefix (可选[str]) –
trim_blocks (bool) –
lstrip_blocks (bool) –
扩展(序列[联合[str, 类型[扩展]]]) –
优化 (bool) –
undefined (Type[jinja2.runtime.Undefined]) –
finalize (可选[Callable[[...[ X90X]],任何]]) –
autoescape (Union[bool,Callable[ [可选[str]][X1717X] X184X]bool]]) –
loader (可选[BaseLoader]) –
cache_size (int) –
auto_reload (bool) –
bytecode_cache (可选[BytecodeCache]) –
- 返回类型
- 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 版中的新功能。
- 参数
扩展 (联合[str,类型[ 扩展]]) –
- 返回类型
没有任何
- 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 版中的新功能。
- 参数
source (str) –
undefined_to_none (bool) –
- 返回类型
jinja2.environment.TemplateExpression
- compile_templates(target, extensions=None, filter_func=None, zip='deflated', log_function=None, ignore_errors=True)
查找加载器可以找到的所有模板,编译它们并将它们存储在 target 中。 如果 zip 是 None,则模板将存储在一个目录中,而不是在 zipfile 中。 默认情况下使用 deflate zip 算法。 要切换到存储算法,可以将zip设置为
'stored'
。extensions 和 filter_func 被传递给 list_templates()。 返回的每个模板都将编译到目标文件夹或 zipfile。
默认情况下,模板编译错误被忽略。 如果提供了日志功能,则会记录错误。 如果您希望模板语法错误中止编译,您可以将 ignore_errors 设置为 False,您将收到语法错误异常。
2.4 版中的新功能。
- 参数
目标 (联合[str,os.PathLike][ X89X]) –
扩展(可选[集合[str] ]) –
filter_func (可选[Callable[[str ]、bool]]) –
zip (可选[str]) –
log_function (可选[Callable[[str ]、无]]) –
ignore_errors (bool) –
- 返回类型
没有任何
- extend(**attributes)
如果项目尚不存在,请将项目添加到环境的实例中。 extensions 使用它来注册回调和配置值,而不会破坏继承。
- 参数
属性 (Any) –
- 返回类型
没有任何
- from_string(source, globals=None, template_class=None)
不使用
loader
从源字符串加载模板。- 参数
source (Union[str,jinja2.nodes.Template ]) – 编译成模板的 Jinja 源代码。
全局变量(可选[映射[str, Any]]) – 使用这些额外的变量扩展环境 globals 可用于此模板的所有渲染。 如果模板已经被加载和缓存,它的全局变量会更新为任何新项目。
template_class (可选[类型[jinja2.environment.Template ]]) – 返回这个 Template 类的实例。
- 返回类型
- get_or_select_template(template_name_or_list, parent=None, globals=None)
如果给出了一个可迭代的模板名称,则使用 select_template(),如果给出一个名称,则使用 get_template()。
2.3 版中的新功能。
- 参数
template_name_or_list (Union[str, jinja2.environment.Template[X111X] , 列表[联合[str[XjinX26X][XjinX26X] .environment.Template]]]) –
父(可选[str]) –
全局变量(可选[映射[str, 任何]]) –
- 返回类型
- get_template(name, parent=None, globals=None)
使用
loader
按名称加载模板并返回 Template。 如果模板不存在,则会引发 TemplateNotFound 异常。- 参数
名称 (联盟[str,jinja2.environment.Template ]) – 要加载的模板的名称。
parent (Optional[str]) – 导入该模板的父模板的名称。 join_path() 可用于实现名称转换。
全局变量(可选[映射[str, Any]]) – 使用这些额外的变量扩展环境 globals 可用于此模板的所有渲染。 如果模板已经被加载和缓存,它的全局变量会更新为任何新项目。
- 返回类型
在 3.0 版更改: 如果从缓存加载模板,
globals
将更新模板的全局变量而不是忽略新值。2.4 版更改: 如果
name
是 Template 对象,则返回不变。
- join_path(template, parent)
与父母一起加入模板。 默认情况下,所有查找都相对于加载程序根目录,因此此方法返回 template 参数不变,但如果路径应该相对于父模板,则可以使用此函数计算真实模板名称。
子类可以覆盖此方法并在此处实现模板路径连接。
- 参数
模板 (str) –
父 (str) –
- 返回类型
字符串
- list_templates(extensions=None, filter_func=None)
返回此环境的模板列表。 这需要加载器支持加载器的
list_templates()
方法。如果模板文件夹中除了实际模板之外还有其他文件,可以过滤返回的列表。 有两种方法:要么将 extensions 设置为模板的文件扩展名列表,要么可以提供一个 filter_func,它是一个可调用的,它传递了一个模板名称并且应该返回 [ X209X]True 如果它应该在结果列表中结束。
如果加载程序不支持,则会引发
TypeError
。2.4 版中的新功能。
- 参数
扩展(可选[集合[str] ]) –
filter_func (可选[Callable[[str ]、bool]]) –
- 返回类型
列表[str]
- select_template(names, parent=None, globals=None)
类似于 get_template(),但尝试加载多个名称。 如果无法加载任何名称,则会引发 TemplatesNotFound 异常。
- 参数
names (Iterable[Union[str, jinja2.environment.Template]]) – 尝试按顺序加载的模板名称列表。
parent (Optional[str]) – 导入该模板的父模板的名称。 join_path() 可用于实现名称转换。
全局变量(可选[映射[str, Any]]) – 使用这些额外的变量扩展环境 globals 可用于此模板的所有渲染。 如果模板已经被加载和缓存,它的全局变量会更新为任何新项目。
- 返回类型
在 3.0 版更改: 如果从缓存加载模板,
globals
将更新模板的全局变量而不是忽略新值。2.11 版更改: 如果
names
是 Undefined,则会引发 UndefinedError。 如果未找到模板且names
包含 Undefined,则该消息更有帮助。2.4 版更改: 如果
names
包含 Template 对象,则返回不变。2.3 版中的新功能。
- class jinja2.Template(source, block_start_string='{%', block_end_string='%}', variable_start_string='{{', variable_end_string='}}', comment_start_string='{#', comment_end_string='#}', line_statement_prefix=None, line_comment_prefix=None, trim_blocks=False, lstrip_blocks=False, newline_sequence='\n', keep_trailing_newline=False, extensions=(), optimized=True, undefined=<class 'jinja2.runtime.Undefined'>, finalize=None, autoescape=False, enable_async=False)
中央模板对象。 这个类代表一个编译的模板并用于评估它。
通常模板对象是从 Environment 生成的,但它也有一个构造函数,可以直接使用构造函数创建模板实例。 它采用与环境构造函数相同的参数,但无法指定加载器。
每个模板对象都有一些保证存在的方法和成员。 然而,模板对象应该被认为是不可变的,这一点很重要。 不支持对对象进行修改。
从构造函数而不是环境创建的模板对象确实具有 environment 属性,该属性指向一个临时环境,该环境可能与使用构造函数和兼容设置创建的其他模板共享。
>>> template = Template('Hello {{ name }}!') >>> template.render(name='John Doe') == u'Hello John Doe!' True >>> stream = template.stream(name='John Doe') >>> next(stream) == u'Hello John Doe!' True >>> next(stream) Traceback (most recent call last): ... StopIteration
- 参数
source (Union[str,jinja2.nodes.Template ]) –
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]) –
line_comment_prefix (可选[str]) –
trim_blocks (bool) –
lstrip_blocks (bool) –
'newline_sequence (te.Literal['\n',' ]\r\n', \r']) –
keep_trailing_newline (bool) –
扩展(序列[联合[str, 类型[扩展]]]) –
优化 (bool) –
undefined (Type[jinja2.runtime.Undefined]) –
finalize (可选[Callable[[...[ X90X]],任何]]) –
autoescape (Union[bool,Callable[ [可选[str]][X1717X] X184X]bool]]) –
enable_async (bool) –
- 返回类型
任何
- globals
每次渲染模板时都可用的变量字典,无需在渲染期间传递它们。 这不应被修改,因为根据模板的加载方式,它可能会与环境和其他模板共享。
默认为 Environment.globals,除非额外的值传递给 Environment.get_template()。
全局变量仅用于模板的每个渲染器共有的数据。 具体数据应该传递给 render()。
参见 全局命名空间 。
- name
模板的加载名称。 如果模板是从字符串加载的,则为 None。
- filename
文件系统上模板的文件名,如果它是从那里加载的。 否则这是 无 。
- render([context])
此方法接受与 dict 构造函数相同的参数:一个 dict、一个 dict 子类或一些关键字参数。 如果没有给出参数,则上下文将为空。 这两个调用执行相同的操作:
template.render(knights='that say nih') template.render({'knights': 'that say nih'})
这将以字符串形式返回呈现的模板。
- 参数
args (Any) –
kwargs (Any) –
- 返回类型
字符串
- generate([context])
对于非常大的模板,最好不要一次渲染整个模板,而是一个接一个地评估每个语句并逐块生成。 这个方法基本上就是这样做的,并返回一个生成器,该生成器以字符串的形式产生一个又一个项目。
它接受与 render() 相同的参数。
- 参数
args (Any) –
kwargs (Any) –
- 返回类型
迭代器[str]
- stream([context])
与 generate() 完全一样,但返回
TemplateStream
。- 参数
args (Any) –
kwargs (Any) –
- 返回类型
- async render_async([context])
这与 render() 类似,但返回一个协程,当等待时返回整个渲染的模板字符串。 这需要启用异步功能。
用法示例:
await template.render_async(knights='that say nih; asynchronously')
- 参数
args (Any) –
kwargs (Any) –
- 返回类型
字符串
- generate_async([context])
generate() 的异步版本。 工作原理非常相似,但返回一个异步迭代器。
- 参数
args (Any) –
kwargs (Any) –
- 返回类型
异步迭代器[str]
- make_module(vars=None, shared=False, locals=None)
当不带参数调用时,此方法的工作方式类似于 module 属性,但它将在每次调用时评估模板,而不是缓存它。 也可以提供一个 dict,然后将其用作上下文。 参数与 new_context() 方法相同。
- 参数
vars(可选[Dict[str, 任何]]) –
shared (bool) –
locals(可选[映射[str, 任何]]) –
- 返回类型
jinja2.environment.TemplateModule
- property module: jinja2.environment.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 将大模板流式传输到客户端,这将非常有用。
- 参数
gen (Iterator[str]) –
- 返回类型
没有任何
- disable_buffering()
禁用输出缓冲。
- 返回类型
没有任何
- dump(fp, encoding=None, errors='strict')
将完整的流转储到文件或类似文件的对象中。 写入默认字符串,如果您想在写入之前进行编码,请指定 encoding。
用法示例:
Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
- 参数
fp (联合[str,IO] ) –
编码 (可选[str]) –
errors (Optional[str]) –
- 返回类型
没有任何
- enable_buffering(size=5)
启用缓冲。 在产生它们之前缓冲 size 项。
- 参数
大小 (int) –
- 返回类型
没有任何
自动转义
在 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) –
默认 (bool) –
- 返回类型
可调用[[../可选[str]],布尔]
这里推荐的设置为以 '.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 块临时更改行为(请参阅 Autoescape Overrides)。
关于标识符的说明
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]) –
obj (Any) –
名称 (可选[str]) –
exc (Type[jinja2.exceptions.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]) –
obj (Any) –
名称 (可选[str]) –
exc (Type[jinja2.exceptions.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]) –
obj (Any) –
名称 (可选[str]) –
exc (Type[jinja2.exceptions.TemplateRuntimeError]) –
- 返回类型
没有任何
- class jinja2.StrictUndefined
一个 undefined 对打印和迭代以及布尔测试和各种比较大吼大叫。 换句话说:除了检查它是否是使用 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]) –
obj (Any) –
名称 (可选[str]) –
exc (Type[jinja2.exceptions.TemplateRuntimeError]) –
- 返回类型
没有任何
还有一个工厂函数可以修饰未定义的对象来实现失败的日志记录:
- jinja2.make_logging_undefined(logger=None, base=<class 'jinja2.runtime.Undefined'>)
给定一个记录器对象,它返回一个新的未定义类,该类将记录某些失败。 它将记录迭代和打印。 如果没有给定记录器,则会创建一个默认记录器。
例子:
logger = logging.getLogger(__name__) LoggingUndefined = make_logging_undefined( logger=logger, base=Undefined )
2.8 版中的新功能。
- 参数
logger (Optional[logging.Logger]) – 要使用的记录器。 如果未提供,则创建默认记录器。
base (Type[jinja2.runtime.Undefined]) – 添加日志功能的基类. 默认为 未定义 。
- 返回类型
未定义的对象是通过调用 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、[ X138X]itervalues、iteritems、__getitem__、__contains__)。 此外,还有一个 resolve() 方法不会因 KeyError 而失败,但会返回一个 Undefined 对象来丢失变量。
- 参数
- parent
模板查找的只读全局变量的字典。 它们可以来自另一个 Context、
Environment.globals
或Template.globals
,也可以指向通过将全局变量与传递给渲染函数的变量相结合而创建的字典。 不得更改。
- vars
模板局部变量。 此列表包含来自 parent 范围的环境和上下文函数,以及来自模板的本地修改和导出变量。 模板将在模板评估期间修改此字典,但不允许过滤器和上下文函数修改它。
- environment
加载模板的环境。
- exported_vars
该集合包含模板导出的所有名称。 名称的值在 vars 字典中。 为了获得导出变量的副本作为 dict,可以使用 get_exported()。
- name
拥有此上下文的模板的加载名称。
- blocks
带有模板中块的当前映射的字典。 这个字典中的键是块的名称,值是已注册的块列表。 每个列表中的最后一项是当前活动块(继承链中最新的)。
- eval_ctx
当前 评估上下文 。
- call(callable, \*args, \**kwargs)
使用提供的参数和关键字参数调用可调用对象,但如果可调用对象具有
pass_context()
或pass_environment()
,则将活动上下文或环境作为第一个参数注入。- 参数
_Context__obj (Callable) –
args (Any) –
kwargs (Any) –
- 返回类型
Union[Any, jinja2.runtime.Undefined]
- get(key, default=None)
按名称查找变量,如果未找到键,则返回默认值。
- 参数
key (str) – 要查找的变量名称。
default (Optional[Any]) – 如果未找到密钥,则返回值。
- 返回类型
任何
- get_all()
将完整的上下文作为 dict 返回,包括导出的变量。 出于优化原因,这可能不会返回实际副本,因此请小心使用它。
- 返回类型
字典[str, 任何]
- get_exported()
使用导出的变量获取新的 dict。
- 返回类型
字典[str, 任何]
- resolve(key)
按名称查找变量,如果未找到键,则返回 Undefined 对象。
如果您需要添加自定义行为,请覆盖 resolve_or_missing(),而不是此方法。 各种查找函数使用该方法,而不是这个方法。
- 参数
key (str) – 要查找的变量名称。
- 返回类型
Union[Any, jinja2.runtime.Undefined]
执行
上下文是不可变的,原因与 Python 的框架局部变量在函数内部不可变的原因相同。 Jinja 和 Python 都没有使用上下文/框架局部变量作为变量的数据存储,而只是作为主要数据源。
当模板访问模板未定义的变量时,Jinja 在上下文中查找该变量,然后将该变量视为已在模板中定义。
装载机
加载器负责从文件系统等资源加载模板。 环境将像 Python 的 sys.modules 一样将编译后的模块保存在内存中。 与 sys.modules 不同的是,默认情况下该缓存的大小是有限的,并且模板会自动重新加载。 所有加载器都是 BaseLoader 的子类。 如果你想创建你自己的加载器,子类 BaseLoader 并覆盖 get_source。
- class jinja2.BaseLoader
所有加载器的基类。 子类化并覆盖 get_source 以实现自定义加载机制。 环境提供了get_template方法,调用loader的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 模板将被重新加载。
- 参数
环境 (环境) –
模板 (str) –
- 返回类型
元组[str, Optional[str], Optional[Callable[[], bool]]]
- load(environment, name, globals=None)
加载模板。 此方法在缓存中查找模板或通过调用 get_source() 加载模板。 子类不应覆盖此方法,因为在其他加载器的集合上工作的加载器(例如 PrefixLoader 或 ChoiceLoader)不会调用此方法,而是直接调用 get_source。
以下是 Jinja 提供的内置加载器列表:
- class jinja2.FileSystemLoader(searchpath, encoding='utf-8', followlinks=False)
从文件系统中的目录加载模板。
路径可以是相对的或绝对的。 相对路径是相对于当前工作目录的。
loader = FileSystemLoader("templates")
可以给出路径列表。 将按顺序搜索目录,在第一个匹配的模板处停止。
loader = FileSystemLoader(["/override/templates", "/default/templates"])
- 参数
searchpath (Union[str,os.PathLike,[ X94X]序列[联合[str,' ]]]) – 包含模板的目录的路径或路径列表。
encoding (str) – 使用此编码从模板文件中读取文本。
followlinks (bool) – 跟随路径中的符号链接。
- 返回类型
没有任何
2.8 版变更: 增加了
followlinks
参数。
- class jinja2.PackageLoader(package_name, package_path='templates', encoding='utf-8')
从 Python 包中的目录加载模板。
- 参数
package_name (str) – 包含模板目录的包的导入名称。
package_path (str) – 包含模板的导入包中的目录。
encoding (str) – 模板文件的编码。
- 返回类型
没有任何
以下示例在
project.ui
包内的pages
目录中查找模板。loader = PackageLoader("project.ui", "pages")
仅支持作为目录(标准 pip 行为)或 zip/egg 文件(不太常见)安装的软件包。 用于内省包中数据的 Python API 太有限,无法支持此加载程序所需的其他安装方法。
对 PEP 420 命名空间包的支持有限。 假定模板目录仅位于一个命名空间贡献者中。 不支持对命名空间有贡献的 Zip 文件。
3.0 版更改: 不再使用
setuptools
作为依赖项。3.0 版更改: 有限的 PEP 420 命名空间包支持。
- class jinja2.DictLoader(mapping)
从 Python 字典中加载模板,将模板名称映射到模板源。 这个加载器对于单元测试很有用:
>>> loader = DictLoader({'index.html': 'source here'})
因为自动重新加载很少有用,所以默认情况下是禁用的。
- 参数
映射 (映射[str,str] ) –
- 返回类型
没有任何
- class jinja2.FunctionLoader(load_func)
一个加载器,它传递了一个执行加载的函数。 该函数接收模板的名称,如果模板不存在,则必须返回带有模板源的字符串,格式为
(source, filename, uptodatefunc)
或 None 的元组。>>> def load_template(name): ... if name == 'index.html': ... return '...' ... >>> loader = FunctionLoader(load_template)
uptodatefunc 是一个函数,如果启用自动重新加载,则调用该函数,如果模板仍然是最新的,则必须返回 True。 有关更多详细信息,请查看具有相同返回值的 BaseLoader.get_source()。
- 参数
load_func (Callable[[str], 可选[联合[str,[X170X170X] X186X][str, 可选[str ], 可选[可调用[[../[X3395X]]X]X , bool]]]]][X446] ) –
- 返回类型
没有任何
- 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,jinja2.loaders.BaseLoader ]) –
定界符 (str) –
- 返回类型
没有任何
- class jinja2.ChoiceLoader(loaders)
这个加载器的工作方式类似于 PrefixLoader,只是没有指定前缀。 如果一个加载器无法找到模板,则尝试下一个加载器。
>>> loader = ChoiceLoader([ ... FileSystemLoader('/path/to/user/templates'), ... FileSystemLoader('/path/to/system/templates') ... ])
如果您希望允许用户覆盖来自不同位置的内置模板,这将非常有用。
- 参数
loaders (Sequence[jinja2.loaders.BaseLoader]) –
- 返回类型
没有任何
- class jinja2.ModuleLoader(path)
这个加载器从预编译的模板中加载模板。
用法示例:
>>> loader = ChoiceLoader([ ... ModuleLoader('/path/to/compiled/templates'), ... FileSystemLoader('/path/to/templates') ... ])
可以使用 Environment.compile_templates() 预编译模板。
- 参数
path (Union[str, os.PathLike,[ X88X]序列[联合[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 的一部分。
- clear()
清除缓存。 Jinja 不使用此方法,但应实现该方法以允许应用程序清除特定环境使用的字节码缓存。
- 返回类型
没有任何
- dump_bytecode(bucket)
子类必须重写此方法才能将字节码从存储桶写回缓存。 如果它不能这样做,它不能静默失败,而是引发异常。
- 参数
bucket (jinja2.bccache.Bucket) –
- 返回类型
没有任何
- load_bytecode(bucket)
子类必须重写此方法才能将字节码加载到存储桶中。 如果他们无法在存储桶的缓存中找到代码,它就不能做任何事情。
- 参数
bucket (jinja2.bccache.Bucket) –
- 返回类型
没有任何
- class jinja2.bccache.Bucket(environment, key, checksum)
桶用于存储一个模板的字节码。 它由字节码缓存创建和初始化,并传递给加载函数。
存储桶从分配的缓存中获取内部校验和,并使用它来自动拒绝过时的缓存材料。 单个字节码缓存子类不必关心缓存失效。
- 参数
环境 (环境) –
key (str) –
校验和 (str) –
- 返回类型
没有任何
- environment
创建存储桶的
Environment
。
- key
此存储桶的唯一缓存键
- code
字节码(如果已加载),否则为 None。
- bytecode_from_string(string)
从字节加载字节码。
- 参数
string (bytes) –
- 返回类型
没有任何
- bytecode_to_string()
将字节码作为字节返回。
- 返回类型
字节
- load_bytecode(f)
从文件或文件类对象加载字节码。
- 参数
f (BinaryIO) –
- 返回类型
没有任何
- reset()
重置存储桶(卸载字节码)。
- 返回类型
没有任何
- write_bytecode(f)
将字节码转储到传递的文件或文件中。
- 参数
f (BinaryIO) –
- 返回类型
没有任何
内置字节码缓存:
- class jinja2.FileSystemBytecodeCache(directory=None, pattern='__jinja2_%s.cache')
在文件系统上存储字节码的字节码缓存。 它接受两个参数:存储缓存项的目录和用于构建文件名的模式字符串。
如果未指定目录,则选择默认缓存目录。 在 Windows 上,使用用户的临时目录,在 UNIX 系统上,在系统临时目录中为用户创建一个目录。
该模式可用于在同一目录上运行多个单独的缓存。 默认模式为
'__jinja2_%s.cache'
。%s
替换为缓存键。>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
此字节码缓存支持使用 clear 方法清除缓存。
- 参数
目录 (可选[str]) –
模式 (str) –
- 返回类型
没有任何
- class jinja2.MemcachedBytecodeCache(client, prefix='jinja2/bytecode/', timeout=None, ignore_memcache_errors=True)
此类实现了一个字节码缓存,该缓存使用 memcache 缓存来存储信息。 它不强制执行特定的 memcache 库(tummy 的 memcache 或 cmemcache),但会接受任何提供所需最小接口的类。
与此类兼容的库:
(遗憾的是django缓存接口不兼容,因为它不支持存储二进制数据,只支持文本。 但是,您可以将底层缓存客户端传递给字节码缓存,该缓存可用作 django.core.cache.cache._client。)
传递给构造函数的客户端的最小接口是这样的:
- 参数
client (_MemcachedClient) –
前缀 (str) –
超时 (可选[int]) –
ignore_memcache_errors (bool) –
- class MinimalClientInterface
- set(key, value[, timeout])
将字节码存储在缓存中。 value 是一个字符串,timeout 是密钥的超时时间。 如果超时未提供默认超时或不应该假定超时,如果提供它是一个整数,缓存项应该存在的秒数。
- get(key)
返回缓存键的值。 如果缓存中不存在该项,则返回值必须为 None。
构造函数的其他参数是在实际缓存键之前添加的所有键的前缀和缓存系统中字节码的超时。 我们建议高(或没有)超时。
此字节码缓存不支持清除缓存中使用的项目。 clear 方法是一个无操作函数。
2.7 新功能: 通过 ignore_memcache_errors 参数添加了对忽略内存缓存错误的支持。
异步支持
2.9 版中的新功能。
Jinja 支持 Python async
和 await
语法。 对于模板设计者来说,这种支持(启用时)是完全透明的,模板继续看起来完全一样。 但是,开发人员应该了解实现,因为它会影响您可以使用的 API 类型。
默认情况下,异步支持被禁用。 启用它会导致环境在幕后编译不同的代码,以便在 asyncio 事件循环中处理异步和同步代码。 这具有以下含义:
- 模板渲染需要一个可供当前线程使用的事件循环。
asyncio.get_running_loop()
必须返回一个事件循环。 - 编译后的代码使用
await
表示函数和属性,并使用async for
循环。 为了支持在此上下文中同时使用异步和同步函数,在所有调用和访问周围放置了一个小包装器,与纯异步代码相比,这增加了开销。 - 同步方法和过滤器在需要时成为其相应异步实现的包装器。 例如,
render
调用async_render
,而|map
支持异步迭代。
Awaitable 对象可以从模板中的函数返回,模板中的任何函数调用都将自动等待结果。 通常在 Python 中添加的 await
是隐含的。 例如,您可以提供一个从数据库异步加载数据的方法,从模板设计者的角度来看,它可以像任何其他函数一样被调用。
政策
从 Jinja 2.9 开始,可以在环境中配置策略,这会稍微影响过滤器和其他模板结构的行为。 它们可以使用 policies 属性进行配置。
例子:
env.policies['urlize.rel'] = 'nofollow noopener'
truncate.leeway
:- 配置 truncate 过滤器的默认余量。 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 Extension 的
{% trans %}
块将始终统一换行符和周围的空格,就像使用了 trimmed 修饰符一样.
公用事业
如果您将自定义过滤器或函数添加到 Jinja 环境,这些辅助函数和类会很有用。
- jinja2.pass_context(f)
在渲染模板时调用时,将 Context 作为第一个参数传递给装饰函数。
可用于函数、过滤器和测试。
如果只需要
Context.eval_context
,请使用 pass_eval_context()。 如果只需要Context.environment
,请使用 pass_environment()。3.0.0 版新功能: 替换
contextfunction
和contextfilter
。- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.pass_eval_context(f)
在渲染模板时调用时,将 EvalContext 作为第一个参数传递给装饰函数。 参见 评估上下文 。
可用于函数、过滤器和测试。
如果只需要
EvalContext.environment
,请使用 pass_environment()。3.0.0 版新功能: 替换
evalcontextfunction
和evalcontextfilter
。- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.pass_environment(f)
在渲染模板时调用时,将 Environment 作为第一个参数传递给装饰函数。
可用于函数、过滤器和测试。
3.0.0 版新功能: 替换
environmentfunction
和environmentfilter
。- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.contextfilter(f)
将上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_context()。
- 参数
f (jinja2.filters.F) –
- 返回类型
jinja2.filters.F
- jinja2.evalcontextfilter(f)
将 eval 上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_eval_context()。
2.4 版中的新功能。
- 参数
f (jinja2.filters.F) –
- 返回类型
jinja2.filters.F
- jinja2.environmentfilter(f)
将环境作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_environment()。
- 参数
f (jinja2.filters.F) –
- 返回类型
jinja2.filters.F
- jinja2.contextfunction(f)
将上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_context()。
- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.evalcontextfunction(f)
将 eval 上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_eval_context()。
2.4 版中的新功能。
- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.environmentfunction(f)
将环境作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 改用 pass_environment()。
- 参数
f (jinja2.utils.F) –
- 返回类型
jinja2.utils.F
- jinja2.clear_caches()
- Jinja 为环境和词法分析器保留内部缓存。 使用这些是为了让 Jinja 不必一直重新创建环境和词法分析器。 通常你不必关心这个,但如果你正在测量内存消耗,你可能想要清理缓存。
- 返回类型
- 没有任何
- jinja2.is_undefined(obj)
检查传递的对象是否未定义。 这只不过是对 Undefined 执行实例检查,但看起来更好。 这可用于想要对未定义变量做出反应的自定义过滤器或测试。 例如,自定义默认过滤器可能如下所示:
def default(var, default=''): if is_undefined(var): return default return var
- 参数
obj (Any) –
- 返回类型
布尔值
例外
- exception jinja2.TemplateError(message=None)
- 所有模板错误的基类。
- 参数
- message (可选[str]) –
- 返回类型
- 没有任何
- exception jinja2.UndefinedError(message=None)
- 如果模板尝试对 Undefined 进行操作,则会引发。
- 参数
- message (可选[str]) –
- 返回类型
- 没有任何
- exception jinja2.TemplateNotFound(name, message=None)
如果模板不存在则引发。
在 2.11 版中更改: 如果给定名称为 Undefined 并且未提供任何消息,则会引发 UndefinedError。
- 参数
名称 (可选[联合[str, 未定义]]) –
message (可选[str]) –
- 返回类型
没有任何
- exception jinja2.TemplatesNotFound(names=(), message=None)
像 TemplateNotFound 但如果选择了多个模板,则会引发。 这是 TemplateNotFound 异常的子类,所以只要捕获基本异常就会捕获两者。
在 2.11 版中更改: 如果名称列表中的名称为 Undefined,则会显示有关它未定义的消息而不是空字符串。
2.2 版中的新功能。
- 参数
名称(序列[联合[str, 未定义]]) –
message (可选[str]) –
- 返回类型
没有任何
- exception jinja2.TemplateSyntaxError(message, lineno, name=None, filename=None)
提出来告诉用户模板有问题。
- 参数
message (str) –
lineno (int) –
名称 (可选[str]) –
文件名 (可选[str]) –
- 返回类型
没有任何
- message
错误信息。
- lineno
发生错误的行号。
- name
模板的加载名称。
- filename
以文件系统的编码加载模板的文件名(最有可能是 utf-8,或 Windows 系统上的 mbcs)。
- exception jinja2.TemplateRuntimeError(message=None)
- 模板引擎中的一般运行时错误。 在某些情况下,Jinja 可能会引发此异常。
- 参数
- message (可选[str]) –
- 返回类型
- 没有任何
- exception jinja2.TemplateAssertionError(message, lineno, name=None, filename=None)
- 类似于模板语法错误,但涵盖了模板中的某些内容在编译时导致错误的情况,而这些错误不一定是由语法错误引起的。 然而,它是 TemplateSyntaxError 的直接子类并且具有相同的属性。
- 参数
- ;;* message (str) –
- lineno (int) –
- 名称 (可选[str]) –
- 文件名 (可选[str]) –
- 返回类型
- 没有任何
自定义过滤器
过滤器是 Python 函数,它将过滤器左侧的值作为第一个参数并产生一个新值。 传递给过滤器的参数在值之后传递。
例如,过滤器 模板:42
在幕后被称为 myfilter(42, 23)
。
Jinja 带有一些 内置过滤器 。 要使用自定义过滤器,请编写一个至少接受 value
参数的函数,然后在 Environment.filters 中注册它。
这是一个格式化日期时间对象的过滤器:
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_environment() 通过 Environment。
- pass_eval_context() 通过 评估上下文 。
- 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
自定义测试
Test 是 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_environment() 通过 Environment。
- pass_eval_context() 通过 评估上下文 。
- 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)
保存评估时间信息。 自定义属性可以在扩展中附加到它。
- 参数
环境 (环境) –
template_name (可选[str]) –
- 返回类型
没有任何
- autoescape
True 或 False 取决于自动转义是否处于活动状态。
- volatile
True 如果编译器在编译时无法计算某些表达式。 在运行时,这应该总是 False。
全局命名空间
全局命名空间存储应该可用的变量和函数,而无需将它们传递给 Template.render()。 它们也可用于在没有上下文的情况下导入或包含的模板。 大多数应用程序应该只使用 Environment.globals。
Environment.globals 适用于该环境加载的所有模板共有的数据。 Template.globals 用于该模板的所有渲染通用的数据,默认为 Environment.globals,除非它们在 Environment.get_template()[ X194X]等。 特定于渲染的数据应作为上下文传递给 Template.render()。
在任何特定渲染期间只使用一组全局变量。 如果模板 A 和 B 都有模板全局变量,并且 B 扩展了 A,那么在使用 b.render()
时,只有 B 的全局变量用于两者。
加载任何模板后不应更改环境全局变量,加载模板后任何时候都不应更改模板全局变量。 加载模板后更改全局变量将导致意外行为,因为它们可能在环境和其他模板之间共享。
低级 API
低级 API 公开了有助于理解一些实现细节、调试目的或高级 扩展 技术的功能。 除非您确切地知道自己在做什么,否则我们不建议您使用其中任何一个。
- Environment.lex(source, name=None, filename=None)
Lex 给定的源代码并返回一个生成器,该生成器以
(lineno, token_type, value)
的形式将标记生成为元组。 这对于 扩展开发 和调试模板很有用。这不执行预处理。 如果要应用扩展的预处理,则必须通过 preprocess() 方法过滤源。
- 参数
source (str) –
名称 (可选[str]) –
文件名 (可选[str]) –
- 返回类型
迭代器[元组[int,str,str]]
- Environment.parse(source, name=None, filename=None)
解析源代码并返回抽象语法树。 编译器使用此节点树将模板转换为可执行的源代码或字节码。 这对于调试或从模板中提取信息很有用。
如果您正在 开发 Jinja 扩展 ,这将为您提供生成的节点树的良好概览。
- 参数
source (str) –
名称 (可选[str]) –
文件名 (可选[str]) –
- 返回类型
jinja2.nodes.Template
- Environment.preprocess(source, name=None, filename=None)
- 预处理带有所有扩展名的源。 这对于所有解析和编译方法都会自动调用,但 not 用于 lex(),因为在那里您通常只希望对实际源进行标记化。
- 参数
- ;;* source (str) –
- 名称 (可选[str]) –
- 文件名 (可选[str]) –
- 返回类型
- 字符串
- Template.new_context(vars=None, shared=False, locals=None)
为此模板创建一个新的
Context
。 提供的变量将传递给模板。 默认情况下,全局变量被添加到上下文中。 如果 shared 设置为 True,则数据将按原样传递到上下文而不添加全局变量。locals 可以是内部使用的局部变量字典。
- 参数
vars(可选[Dict[str, 任何]]) –
shared (bool) –
locals(可选[映射[str, 任何]]) –
- 返回类型
- Template.root_render_func(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
并且事实上该函数当前也可以引发该异常。- 参数
ast (jinja2.nodes.Template) –
- 返回类型
设置[str]
- 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]
此功能对于依赖项跟踪很有用。 例如,如果您想在布局模板更改后重建网站的某些部分。
- 参数
ast (jinja2.nodes.Template) –
- 返回类型
迭代器[可选[str]]