API — Jinja 文档
应用程序接口
本文档描述的是 Jinja2 的 API,而不是模板语言。 对于那些实现应用程序模板接口的人而不是那些创建 Jinja2 模板的人来说,它是最有用的参考。
基本
Jinja2 使用称为模板 Environment 的中心对象。 此类的实例用于存储配置和全局对象,并用于从文件系统或其他位置加载模板。 即使您使用 Template 类的构造函数从字符串创建模板,也会自动为您创建一个环境,尽管是共享环境。
大多数应用程序会在应用程序初始化时创建一个 Environment 对象并使用它来加载模板。 但是,在某些情况下,如果使用不同的配置,同时拥有多个环境会很有用。
配置 Jinja2 以加载应用程序模板的最简单方法大致如下所示:
这将创建一个具有默认设置的模板环境和一个在 yourapplication python 包内的 templates 文件夹中查找模板的加载器。 可以使用不同的加载器,如果您想从数据库或其他资源加载模板,您也可以编写自己的加载器。 这也为 HTML 和 XML 文件启用自动转义。
要从此环境加载模板,您只需调用 get_template()
方法,然后返回加载的 Template:
要使用一些变量渲染它,只需调用 render()
方法:
使用模板加载器而不是将字符串传递给 Template 或 Environment.from_string() 有很多优点。 除了更容易使用之外,它还支持模板继承。
自动转义注意事项
在 Jinja2 的未来版本中,出于安全原因,我们可能会默认启用自动转义。 因此,鼓励您现在明确配置自动转义,而不是依赖默认值。
统一码
Jinja2 在内部使用 Unicode,这意味着您必须将 Unicode 对象传递给渲染函数或仅包含 ASCII 字符的字节串。 此外,换行符标准化为行序列的一端,这是默认的 UNIX 样式 (\n
)。
Python 2.x 支持两种表示字符串对象的方式。 一个是str类型,另一个是unicode类型,两者都扩展了一个叫做basestring的类型。 不幸的是,默认值是 str,它不应该用于存储基于文本的信息,除非只使用 ASCII 字符。 在 Python 2.6 中,可以将 unicode 设为每个模块级别的默认值,而在 Python 3 中,它将成为默认值。
要明确使用 Unicode 字符串,您必须在字符串文字前加上 u: u'Hänsel und Gretel sagen Hallo'
。 这样,Python 将通过使用当前 Python 模块中的字符编码对字符串进行解码来将字符串存储为 Unicode。 如果未指定编码,则默认为“ASCII”,这意味着您不能使用任何非 ASCII 标识符。
要设置更好的模块编码,请使用 Unicode 文字将以下注释添加到 Python 模块的第一行或第二行:
我们推荐 utf-8 作为 Python 模块和模板的编码,因为它可以表示 utf-8 中的每个 Unicode 字符,并且因为它向后兼容 ASCII。 对于 Jinja2,模板的默认编码假定为 utf-8。
无法使用 Jinja2 处理非 Unicode 数据。 这样做的原因是 Jinja2 已经在语言层面使用了 Unicode。 例如,Jinja2 将不间断空格视为表达式中的有效空格,这需要了解编码或对 Unicode 字符串进行操作。
有关 Python 中 Unicode 的更多详细信息,请查看优秀的 Unicode 文档 。
另一个重要的事情是 Jinja2 如何处理模板中的字符串文字。 一个简单的实现是将 Unicode 字符串用于所有字符串文字,但过去证明这是有问题的,因为某些库明确地针对 str 进行类型检查。 例如 datetime.strftime 不接受 Unicode 参数。 为了不完全破坏它,Jinja2 将返回 str 用于适合 ASCII 的字符串以及其他所有内容 unicode:
高级 API
高级 API 是您将在应用程序中用于加载和呈现 Jinja2 模板的 API。 另一边的 低级 API 仅在您想深入了解 Jinja2 或 开发扩展 时才有用。
- 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,这将启用异步模板执行,允许使用异步函数和生成器。
- shared
如果模板是使用 Template 构造函数创建的,则会自动创建环境。 这些环境被创建为共享环境,这意味着多个模板可能具有相同的匿名环境。 对于所有共享环境,此属性为 True,否则为 False。
- sandboxed
如果环境被沙箱化,则此属性为 True。 对于沙盒模式,请查看 SandboxedEnvironment 的文档。
- policies
带有 策略 的字典。 这些可以重新配置以更改运行时行为或某些模板功能。 通常这些都是安全相关的。
- code_generator_class
用于代码生成的类。 在大多数情况下,这不应更改,除非您需要修改模板编译为的 Python 代码。
- context_class
用于模板的上下文。 在大多数情况下,这不应更改,除非您需要修改模板变量处理方式的内部结构。 有关详细信息,请参阅 上下文 。
- overlay([options])
创建一个新的覆盖环境,该环境与当前环境共享除缓存和覆盖属性之外的所有数据。 无法为覆盖环境删除扩展。 覆盖的环境会自动获取它所链接的环境的所有扩展以及可选的额外扩展。
创建覆盖应该在初始环境完全设置之后发生。 并非所有属性都真正链接在一起,有些只是复制过来,因此对原始环境的修改可能无法体现出来。
- undefined([hint, obj, name, exc])
为 name 创建一个新的 Undefined 对象。 这对于可能为某些操作返回未定义对象的过滤器或函数很有用。 除 hint 之外的所有参数都应作为关键字参数提供,以提高可读性。 如果提供了 hint 作为异常的错误信息,否则错误信息将自动从 obj 和 name 生成。 如果对生成的未定义对象进行了未定义对象不允许的操作,则会引发作为 exc 提供的异常。 默认异常是 UndefinedError。 如果提供了 hint,则可以省略 name。
创建未定义对象的最常见方法是仅提供名称:
这意味着名称 some_name 未定义。 如果名称来自对象的属性,则告诉未定义的对象持有者对象以改进错误消息是有意义的:
对于更复杂的示例,您可以提供提示。 例如
first()
过滤器以这种方式创建一个未定义的对象:如果 name 或 obj 已知(例如因为访问了属性),则应将其传递给未定义的对象,即使自定义 hint 是假如。 这为未定义的对象提供了增强错误消息的可能性。
- add_extension(extension: Union[str, Type[Extension]]) None
在创建环境后添加扩展。
2.5 版中的新功能。
- compile_expression(source: str, undefined_to_none: bool = True) jinja2.environment.TemplateExpression
一个方便的辅助方法,它返回一个可调用对象,它接受在表达式中作为变量出现的关键字参数。 如果调用它返回表达式的结果。
如果应用程序希望在模板“配置文件”或类似情况下使用与 Jinja 相同的规则,这将非常有用。
用法示例:
默认情况下,如果表达式返回未定义的值,则返回值将转换为 None。 这可以通过将 undefined_to_none 设置为 False 来更改。
2.1 版中的新功能。
- compile_templates(target: Union[str, os.PathLike], extensions: Optional[Collection[str]] = None, filter_func: Optional[Callable[[str], bool]] = None, zip: Optional[str] = 'deflated', log_function: Optional[Callable[[str], None]] = None, ignore_errors: bool = True) None
查找加载器可以找到的所有模板,编译它们并将它们存储在 target 中。 如果 zip 是 None,则模板将存储在一个目录中,而不是在 zipfile 中。 默认情况下使用 deflate zip 算法。 要切换到存储算法,可以将zip设置为
'stored'
。extensions 和 filter_func 被传递给 list_templates()。 返回的每个模板都将编译到目标文件夹或 zipfile。
默认情况下,模板编译错误被忽略。 如果提供了日志功能,则会记录错误。 如果您希望模板语法错误中止编译,您可以将 ignore_errors 设置为 False,您将收到语法错误异常。
2.4 版中的新功能。
- extend(**attributes: Any) None
如果项目尚不存在,请将项目添加到环境的实例中。 extensions 使用它来注册回调和配置值,而不会破坏继承。
- from_string(source: Union[str, jinja2.nodes.Template], globals: Optional[Mapping[str, Any]] = None, template_class: Optional[Type[jinja2.environment.Template]] = None) jinja2.environment.Template
不使用
loader
从源字符串加载模板。
- get_or_select_template(template_name_or_list: Union[str, jinja2.environment.Template, List[Union[str, jinja2.environment.Template]]], parent: Optional[str] = None, globals: Optional[Mapping[str, Any]] = None) jinja2.environment.Template
如果给出了一个可迭代的模板名称,则使用 select_template(),如果给出一个名称,则使用 get_template()。
2.3 版中的新功能。
- get_template(name: Union[str, jinja2.environment.Template], parent: Optional[str] = None, globals: Optional[Mapping[str, Any]] = None) jinja2.environment.Template
使用
loader
按名称加载模板并返回 Template。 如果模板不存在,则会引发 TemplateNotFound 异常。- 参数
name – 要加载的模板的名称。
parent – 导入此模板的父模板的名称。 join_path() 可用于实现名称转换。
globals – 扩展环境 globals,这些额外变量可用于该模板的所有渲染。 如果模板已经被加载和缓存,它的全局变量会更新为任何新项目。
在 3.0 版更改: 如果从缓存加载模板,
globals
将更新模板的全局变量而不是忽略新值。2.4 版更改: 如果
name
是 Template 对象,则返回不变。
- join_path(template: str, parent: str) str
与父母一起加入模板。 默认情况下,所有查找都相对于加载程序根目录,因此此方法返回 template 参数不变,但如果路径应该相对于父模板,则可以使用此函数计算真实模板名称。
子类可以覆盖此方法并在此处实现模板路径连接。
- list_templates(extensions: Optional[Collection[str]] = None, filter_func: Optional[Callable[[str], bool]] = None) List[str]
返回此环境的模板列表。 这需要加载器支持加载器的
list_templates()
方法。如果模板文件夹中除了实际模板之外还有其他文件,可以过滤返回的列表。 有两种方法:要么将 extensions 设置为模板的文件扩展名列表,要么可以提供一个 filter_func,它是一个可调用的,它传递了一个模板名称并且应该返回 [ X209X]True 如果它应该在结果列表中结束。
如果加载程序不支持,则会引发
TypeError
。2.4 版中的新功能。
- select_template(names: Iterable[Union[str, jinja2.environment.Template]], parent: Optional[str] = None, globals: Optional[Mapping[str, Any]] = None) jinja2.environment.Template
类似于 get_template(),但尝试加载多个名称。 如果无法加载任何名称,则会引发 TemplatesNotFound 异常。
- 参数
names – 尝试按顺序加载的模板名称列表。
parent – 导入此模板的父模板的名称。 join_path() 可用于实现名称转换。
globals – 扩展环境 globals,这些额外变量可用于该模板的所有渲染。 如果模板已经被加载和缓存,它的全局变量会更新为任何新项目。
在 3.0 版更改: 如果从缓存加载模板,
globals
将更新模板的全局变量而不是忽略新值。2.11 版更改: 如果
names
是 Undefined,则会引发 UndefinedError。 如果未找到模板且names
包含 Undefined,则该消息更有帮助。2.4 版更改: 如果
names
包含 Template 对象,则返回不变。2.3 版中的新功能。
- class jinja2.Template(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: Optional[str] = None, line_comment_prefix: Optional[str] = None, trim_blocks: bool = False, lstrip_blocks: bool = False, newline_sequence: te.Literal['\n', '\r\n', '\r'] = '\n', keep_trailing_newline: bool = False, extensions: Sequence[Union[str, Type[Extension]]] = (), optimized: bool = True, undefined: Type[jinja2.runtime.Undefined] = <class 'jinja2.runtime.Undefined'>, finalize: Optional[Callable[[...], Any]] = None, autoescape: Union[bool, Callable[[../Optional[str]], bool]] = False, enable_async: bool = False)
中央模板对象。 这个类代表一个编译的模板并用于评估它。
通常模板对象是从 Environment 生成的,但它也有一个构造函数,可以直接使用构造函数创建模板实例。 它采用与环境构造函数相同的参数,但无法指定加载器。
每个模板对象都有一些保证存在的方法和成员。 然而,模板对象应该被认为是不可变的,这一点很重要。 不支持对对象进行修改。
从构造函数而不是环境创建的模板对象确实具有 environment 属性,该属性指向一个临时环境,该环境可能与使用构造函数和兼容设置创建的其他模板共享。
- globals
带有该模板全局变量的字典。 修改此 dict 是不安全的,因为它可能与其他模板或加载模板的环境共享。
- name
模板的加载名称。 如果模板是从字符串加载的,则为 None。
- filename
文件系统上模板的文件名,如果它是从那里加载的。 否则这是 无 。
- render([context])
此方法接受与 dict 构造函数相同的参数:一个 dict、一个 dict 子类或一些关键字参数。 如果没有给出参数,则上下文将为空。 这两个调用执行相同的操作:
这将以字符串形式返回呈现的模板。
- generate([context])
对于非常大的模板,最好不要一次渲染整个模板,而是一个接一个地评估每个语句并逐块生成。 这个方法基本上就是这样做的,并返回一个生成器,该生成器以字符串的形式产生一个又一个项目。
它接受与 render() 相同的参数。
- stream([context])
与 generate() 完全一样,但返回
TemplateStream
。
- async render_async([context])
这与 render() 类似,但返回一个协程,当等待时返回整个渲染的模板字符串。 这需要启用异步功能。
用法示例:
- generate_async([context])
generate() 的异步版本。 工作原理非常相似,但返回一个异步迭代器。
- make_module(vars: Optional[Dict[str, Any]] = None, shared: bool = False, locals: Optional[Mapping[str, Any]] = None) jinja2.environment.TemplateModule
当不带参数调用时,此方法的工作方式类似于 module 属性,但它将在每次调用时评估模板,而不是缓存它。 也可以提供一个 dict,然后将其用作上下文。 参数与 new_context() 方法相同。
- property module: jinja2.environment.TemplateModule
模板作为模块。 这用于模板运行时中的导入,但如果想要从 Python 层访问导出的模板变量也很有用:
如果启用了异步模式,则此属性不可用。
- class jinja2.environment.TemplateStream
模板流的工作方式与普通的 Python 生成器非常相似,但它可以缓冲多个项目以减少总迭代次数。 默认情况下,输出是无缓冲的,这意味着对于模板中的每个无缓冲指令都会产生一个字符串。
如果在缓冲区大小为 5 的情况下启用缓冲,则五个项目将组合成一个新字符串。 如果您通过每次迭代后刷新的 WSGI 将大模板流式传输到客户端,这将非常有用。
- disable_buffering() None
禁用输出缓冲。
- dump(fp: Union[str, IO], encoding: Optional[str] = None, errors: Optional[str] = 'strict') None
将完整的流转储到文件或类似文件的对象中。 写入默认字符串,如果您想在写入之前进行编码,请指定 encoding。
用法示例:
- enable_buffering(size: int = 5) None
启用缓冲。 在产生它们之前缓冲 size 项。
自动转义
在 2.4 版中更改。
Jinja2 现在带有自动转义支持。 从 Jinja 2.9 开始,自动转义扩展被移除并内置。 然而,默认情况下尚未启用自动转义,尽管这很可能在未来发生变化。 建议为自动转义配置一个合理的默认值。 这使得可以在每个模板的基础上启用和禁用自动转义(例如 HTML 与文本)。
- jinja2.select_autoescape(enabled_extensions: Collection[str] = ('html', 'htm', 'xml'), disabled_extensions: Collection[str] = (), default_for_string: bool = True, default: bool = False) Callable[[Optional[str]], bool]
根据模板的文件名智能设置自动转义的初始值。 如果您不想自己编写自定义函数,这是配置自动转义的推荐方法。
如果要为所有从字符串创建的模板或所有具有 .html 和 .xml 扩展名的模板启用它:
始终打开它的示例配置,除非模板以 .txt 结尾:
enabled_extensions 是所有应该启用自动转义的扩展的迭代。 同样, disabled_extensions 是所有模板的列表,它应该被禁用。 如果从字符串加载模板,则使用 default_for_string 中的默认值。 如果没有匹配项,则自动转义的初始值设置为 default 的值。
出于安全原因,此功能不区分大小写。
2.9 版中的新功能。
这里推荐的设置为以 '.html'
、'.htm'
和 '.xml'
结尾的模板启用自动转义,并默认为所有其他扩展禁用它。 您可以为此使用 select_autoescape() 函数:
select_autoescape()
函数返回一个大致如下工作的函数:
在实现猜测自动转义功能时,请确保您还接受 None 作为有效模板名称。 这将在从字符串生成模板时传递。 您应该始终配置自动转义,因为将来可能会更改默认值。
在模板内部,可以使用 autoescape 块临时更改行为(请参阅 Autoescape Overrides)。
关于标识符的说明
Jinja2 使用常规的 Python 2.x 命名规则。 有效标识符必须匹配 [a-zA-Z_][a-zA-Z0-9_]*
。 事实上,目前不允许使用非 ASCII 字符。 一旦为 Python 3 完全指定了 unicode 标识符,此限制可能会消失。
过滤器和测试在单独的命名空间中查找,并稍微修改了标识符语法。 过滤器和测试可能包含点以按主题对过滤器和测试进行分组。 例如,将一个函数添加到过滤器字典中并将其称为 to.unicode 是完全有效的。 过滤器和测试标识符的正则表达式是 [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*`
。
未定义类型
这些类可以用作未定义的类型。 Environment 构造函数采用 undefined 参数,该参数可以是这些类之一或 Undefined 的自定义子类。 每当模板引擎无法查找名称或访问属性时,就会创建并返回这些对象之一。 然后允许对未定义值进行某些操作,而其他操作则失败。
最接近常规 Python 行为的是 StrictUndefined,它禁止除了测试它是否是未定义对象之外的所有操作。
- class jinja2.Undefined
默认的未定义类型。 这个未定义的类型可以被打印和迭代,但是每一次访问都会引发一个 UndefinedError:
- _undefined_hint
None 或带有未定义对象错误消息的 unicode 字符串。
- _undefined_obj
None 或导致创建未定义对象的所有者对象(例如,因为属性不存在)。
- _undefined_name
未定义变量/属性的名称,如果不存在此类信息,则为 None。
- _undefined_exception
未定义对象想要引发的异常。 这通常是 UndefinedError 或
SecurityError
之一。
- _fail_with_undefined_error(\*args, \**kwargs)
当使用任何参数调用此方法时,该方法会引发 _undefined_exception 以及从存储在未定义对象上的未定义提示生成的错误消息。
- class jinja2.DebugUndefined
打印时返回调试信息的未定义。
- class jinja2.StrictUndefined
一个 undefined 对打印和迭代以及布尔测试和各种比较大吼大叫。 换句话说:除了检查它是否是使用 defined 测试定义的之外,你不能对它做任何事情。
还有一个工厂函数可以修饰未定义的对象来实现失败的日志记录:
- jinja2.make_logging_undefined(logger: Optional[logging.Logger] = None, base: Type[jinja2.runtime.Undefined] = <class 'jinja2.runtime.Undefined'>) Type[jinja2.runtime.Undefined]
给定一个记录器对象,它返回一个新的未定义类,该类将记录某些失败。 它将记录迭代和打印。 如果没有给定记录器,则会创建一个默认记录器。
例子:
2.8 版中的新功能。
- 参数
logger – 要使用的记录器。 如果未提供,则创建默认记录器。
base – 添加日志功能的基类。 默认为 未定义 。
未定义的对象是通过调用 undefined
创建的。
执行
Undefined 对象是通过覆盖特殊的 __underscore__ 方法实现的。 例如,默认的 Undefined 类以返回空字符串的方式实现了 __unicode__,但是 __int__ 和其他类仍然失败并抛出异常。 要通过返回 0
允许转换为 int,您可以实现自己的:
要禁止一个方法,只需覆盖它并引发 _undefined_exception。 因为这是未定义对象中非常常见的习惯用法,所以有帮助方法 _fail_with_undefined_error() 自动引发错误。 这里有一个类似于常规 Undefined 但在迭代时窒息的类:
上下文
- 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()
,则将活动上下文或环境作为第一个参数注入。
- get_all() Dict[str, Any]
将完整的上下文作为 dict 返回,包括导出的变量。 出于优化原因,这可能不会返回实际副本,因此请小心使用它。
- get_exported() Dict[str, Any]
使用导出的变量获取新的 dict。
- resolve(key: str) Union[Any, jinja2.runtime.Undefined]
按名称查找变量,如果未找到键,则返回 Undefined 对象。
如果您需要添加自定义行为,请覆盖
resolve_or_missing()
,而不是此方法。 各种查找函数使用该方法,而不是这个方法。- 参数
key – 要查找的变量名称。
执行
上下文是不可变的,原因与 Python 的框架局部变量在函数内部不可变的原因相同。 Jinja2 和 Python 都没有使用上下文/框架局部变量作为变量的数据存储,而只是作为主要数据源。
当模板访问模板未定义的变量时,Jinja2 在上下文中查找该变量,然后将该变量视为已在模板中定义。
装载机
加载器负责从文件系统等资源加载模板。 环境将像 Python 的 sys.modules 一样将编译后的模块保存在内存中。 与 sys.modules 不同的是,默认情况下该缓存的大小是有限的,并且模板会自动重新加载。 所有加载器都是 BaseLoader 的子类。 如果你想创建你自己的加载器,子类 BaseLoader 并覆盖 get_source。
- class jinja2.BaseLoader
所有加载器的基类。 子类化并覆盖 get_source 以实现自定义加载机制。 环境提供了get_template方法,调用loader的load方法获取Template对象。
在文件系统上查找模板的加载程序的一个非常基本的示例可能如下所示:
- get_source(environment: Environment, template: str) Tuple[str, Optional[str], Optional[Callable[[], bool]]]
获取模板源、文件名和重新加载模板的帮助程序。 它传递了环境和模板名称,并且必须以
(source, filename, uptodate)
形式返回一个元组,或者如果找不到模板则引发 TemplateNotFound 错误。返回的元组的源部分必须是作为字符串的模板的源。 如果文件是从那里加载的,文件名应该是文件系统上文件的名称,否则为
None
。 如果未使用加载程序扩展名,Python 将使用文件名进行回溯。元组中的最后一项是 uptodate 函数。 如果启用了自动重新加载,则始终会调用它来检查模板是否已更改。 没有传递参数,因此函数必须将旧状态存储在某处(例如在闭包中)。 如果它返回 False 模板将被重新加载。
- load(environment: Environment, name: str, globals: Optional[MutableMapping[str, Any]] = None) Template
加载模板。 此方法在缓存中查找模板或通过调用 get_source() 加载模板。 子类不应覆盖此方法,因为在其他加载器的集合上工作的加载器(例如 PrefixLoader 或 ChoiceLoader)不会调用此方法,而是直接调用 get_source。
这里是 Jinja2 提供的内置加载器列表:
- class jinja2.FileSystemLoader(searchpath: Union[str, os.PathLike, Sequence[Union[str, os.PathLike]]], encoding: str = 'utf-8', followlinks: bool = False)
从文件系统中的目录加载模板。
路径可以是相对的或绝对的。 相对路径是相对于当前工作目录的。
可以给出路径列表。 将按顺序搜索目录,在第一个匹配的模板处停止。
- 参数
searchpath – 包含模板的目录的路径或路径列表。
encoding – 使用此编码从模板文件中读取文本。
followlinks – 跟随路径中的符号链接。
2.8 版变更: 增加了
followlinks
参数。
- class jinja2.PackageLoader(package_name: str, package_path: str = 'templates', encoding: str = 'utf-8')
从 Python 包中的目录加载模板。
- 参数
package_name – 包含模板目录的包的导入名称。
package_path – 包含模板的导入包中的目录。
encoding – 模板文件的编码。
以下示例在
project.ui
包内的pages
目录中查找模板。仅支持作为目录(标准 pip 行为)或 zip/egg 文件(不太常见)安装的软件包。 用于内省包中数据的 Python API 太有限,无法支持此加载程序所需的其他安装方法。
对 PEP 420 命名空间包的支持有限。 假定模板目录仅位于一个命名空间贡献者中。 不支持对命名空间有贡献的 Zip 文件。
3.0 版更改: 不再使用
setuptools
作为依赖项。3.0 版更改: 有限的 PEP 420 命名空间包支持。
- class jinja2.DictLoader(mapping: Mapping[str, str])
从 Python 字典中加载模板,将模板名称映射到模板源。 这个加载器对于单元测试很有用:
因为自动重新加载很少有用,所以默认情况下是禁用的。
- class jinja2.FunctionLoader(load_func: Callable[[str], Optional[Union[str, Tuple[str, Optional[str], Optional[Callable[[], bool]]]]]])
一个加载器,它传递了一个执行加载的函数。 该函数接收模板的名称,如果模板不存在,则必须返回带有模板源的字符串,格式为
(source, filename, uptodatefunc)
或 None 的元组。uptodatefunc 是一个函数,如果启用自动重新加载,则调用该函数,如果模板仍然是最新的,则必须返回 True。 有关更多详细信息,请查看具有相同返回值的 BaseLoader.get_source()。
- class jinja2.PrefixLoader(mapping: Mapping[str, jinja2.loaders.BaseLoader], delimiter: str = '/')
一个加载器,它传递一个加载器字典,其中每个加载器都绑定到一个前缀。 默认情况下,前缀由模板与模板分隔,可以通过将 delimiter 参数设置为其他内容来更改:
通过加载
'app1/index.html'
从 app1 包中加载文件,通过加载'app2/index.html'
从第二个包中加载文件。
- class jinja2.ChoiceLoader(loaders: Sequence[jinja2.loaders.BaseLoader])
这个加载器的工作方式类似于 PrefixLoader,只是没有指定前缀。 如果一个加载器无法找到模板,则尝试下一个加载器。
如果您希望允许用户覆盖来自不同位置的内置模板,这将非常有用。
- class jinja2.ModuleLoader(path: Union[str, os.PathLike, Sequence[Union[str, os.PathLike]]])
这个加载器从预编译的模板中加载模板。
用法示例:
可以使用 Environment.compile_templates() 预编译模板。
字节码缓存
Jinja 2.1 及更高版本支持外部字节码缓存。 字节码缓存可以将生成的字节码存储在文件系统或其他位置,以避免在首次使用时解析模板。
如果您有一个在第一个请求时初始化的 Web 应用程序并且 Jinja 一次编译许多模板从而减慢应用程序的速度,这将特别有用。
要使用字节码缓存,请将其实例化并将其传递给 Environment。
- class jinja2.BytecodeCache
要实现您自己的字节码缓存,您必须继承此类并覆盖 load_bytecode() 和 dump_bytecode()。 这两种方法都传递了一个 Bucket。
一个非常基本的字节码缓存,将字节码保存在文件系统上:
基于文件系统的字节码缓存的更高级版本是 Jinja 的一部分。
- clear() None
清除缓存。 Jinja 不使用此方法,但应实现该方法以允许应用程序清除特定环境使用的字节码缓存。
- dump_bytecode(bucket: jinja2.bccache.Bucket) None
子类必须重写此方法才能将字节码从存储桶写回缓存。 如果它不能这样做,它不能静默失败,而是引发异常。
- load_bytecode(bucket: jinja2.bccache.Bucket) None
子类必须重写此方法才能将字节码加载到存储桶中。 如果他们无法在存储桶的缓存中找到代码,它就不能做任何事情。
- class jinja2.bccache.Bucket(environment: Environment, key: str, checksum: str)
桶用于存储一个模板的字节码。 它由字节码缓存创建和初始化,并传递给加载函数。
存储桶从分配的缓存中获取内部校验和,并使用它来自动拒绝过时的缓存材料。 单个字节码缓存子类不必关心缓存失效。
- environment
创建存储桶的
Environment
。
- key
此存储桶的唯一缓存键
- code
字节码(如果已加载),否则为 None。
- bytecode_from_string(string: bytes) None
从字节加载字节码。
- bytecode_to_string() bytes
将字节码作为字节返回。
- load_bytecode(f: BinaryIO) None
从文件或文件类对象加载字节码。
- reset() None
重置存储桶(卸载字节码)。
- write_bytecode(f: BinaryIO) None
将字节码转储到传递的文件或文件中。
内置字节码缓存:
- class jinja2.FileSystemBytecodeCache(directory: Optional[str] = None, pattern: str = '__jinja2_%s.cache')
在文件系统上存储字节码的字节码缓存。 它接受两个参数:存储缓存项的目录和用于构建文件名的模式字符串。
如果未指定目录,则选择默认缓存目录。 在 Windows 上,使用用户的临时目录,在 UNIX 系统上,在系统临时目录中为用户创建一个目录。
该模式可用于在同一目录上运行多个单独的缓存。 默认模式为
'__jinja2_%s.cache'
。%s
替换为缓存键。此字节码缓存支持使用 clear 方法清除缓存。
- class jinja2.MemcachedBytecodeCache(client: _MemcachedClient, prefix: str = 'jinja2/bytecode/', timeout: Optional[int] = None, ignore_memcache_errors: bool = True)
此类实现了一个字节码缓存,该缓存使用 memcache 缓存来存储信息。 它不强制执行特定的 memcache 库(tummy 的 memcache 或 cmemcache),但会接受任何提供所需最小接口的类。
与此类兼容的库:
(遗憾的是django缓存接口不兼容,因为它不支持存储二进制数据,只支持文本。 但是,您可以将底层缓存客户端传递给字节码缓存,该缓存可用作 django.core.cache.cache._client。)
传递给构造函数的客户端的最小接口是这样的:
- class MinimalClientInterface
- set(key, value[, timeout])
将字节码存储在缓存中。 value 是一个字符串,timeout 是密钥的超时时间。 如果超时未提供默认超时或不应该假定超时,如果提供它是一个整数,缓存项应该存在的秒数。
- get(key)
返回缓存键的值。 如果缓存中不存在该项,则返回值必须为 None。
构造函数的其他参数是在实际缓存键之前添加的所有键的前缀和缓存系统中字节码的超时。 我们建议高(或没有)超时。
此字节码缓存不支持清除缓存中使用的项目。 clear 方法是一个无操作函数。
2.7 新功能: 通过 ignore_memcache_errors 参数添加了对忽略内存缓存错误的支持。
异步支持
从 2.9 版开始,Jinja2 还支持 Python async 和 await 构造。 就模板设计人员而言,此功能对他们来说是完全不透明的,但是作为开发人员,您应该了解它是如何实现的,因为它会影响您可以安全地向模板环境公开的 API 类型。
首先你需要知道默认情况下异步支持是禁用的,因为启用它会在幕后生成不同的模板代码,这些代码通过异步事件循环传递所有内容。 理解这一点很重要,因为它对你正在做的事情有一些影响:
- 模板渲染需要为当前线程设置一个事件循环(
asyncio.get_event_loop
需要返回一个) - 所有模板生成代码都在内部运行异步生成器,这意味着即使使用非同步方法,您也会付出性能损失!
- 如果启用了异步模式,则同步方法基于异步方法,这意味着 render 将在内部调用 render_async 并将其作为当前事件循环的一部分运行,直到执行完成.
Awaitable 对象可以从模板中的函数返回,模板中的任何函数调用都将自动等待结果。 这意味着如果您愿意,您可以提供一个从数据库异步加载数据的方法,从模板设计者的角度来看,这只是他们可以调用的另一个函数。 这意味着您通常会在 Python 中发出的 await
是隐含的。 然而,这仅适用于函数调用。 例如,如果一个属性是一个可用的对象,那么这不会导致预期的行为。
同样,带有 for 循环的迭代支持异步迭代器。
政策
从 Jinja 2.9 开始,可以在环境中配置策略,这会稍微影响过滤器和其他模板结构的行为。 它们可以使用 policies 属性进行配置。
例子:
compiler.ascii_str
:- 这个布尔值控制 Python 2 上的 Jinja2 是否应该仅将 ASCII 文字存储为字节串而不是 unicode 字符串。 过去总是为 2.9 以下的 Jinja 版本启用,现在可以更改。 传统上它是通过这种方式完成的,因为 Python 2 中的某些 API 对 unicode 字符串(例如 datetime strftime API)严重失败。 然而,现在有时相反是正确的(例如 str.format)。 如果将其设置为 False,则所有字符串都在内部存储为 unicode。
truncate.leeway
:- 配置 truncate 过滤器的默认余量。 Leeway 在 2.9 中引入,但为了恢复与旧模板的兼容性,可以将其配置为 0 以恢复旧行为。 默认值为 5。
urlize.rel
:- 使用 urlize 过滤器定义生成链接的 rel 属性项的字符串。 这些项目总是被添加。 默认值为 noopener。
urlize.target
:- 如果调用没有明确定义其他目标,则为来自 urlize 过滤器的链接发出的默认目标。
json.dumps_function
:- 如果将其设置为 None 以外的值,则 tojson 过滤器将使用此函数而不是默认值进行转储。 请注意,此函数应接受将来可能从过滤器传递的任意额外参数。 目前唯一可以传递的参数是 indent。 默认转储功能是
json.dumps
。 json.dumps_kwargs
:- 要传递给转储函数的关键字参数。 默认值为
{'sort_keys': True}
。
公用事业
如果您将自定义过滤器或函数添加到 Jinja2 环境,这些辅助函数和类会很有用。
- jinja2.environmentfilter(f: jinja2.filters.F) jinja2.filters.F
将环境作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_environment()
。
- jinja2.contextfilter(f: jinja2.filters.F) jinja2.filters.F
将上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_context()
。
- jinja2.evalcontextfilter(f: jinja2.filters.F) jinja2.filters.F
将 eval 上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_eval_context()
。2.4 版中的新功能。
- jinja2.environmentfunction(f: jinja2.utils.F) jinja2.utils.F
将环境作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_environment()
。
- jinja2.contextfunction(f: jinja2.utils.F) jinja2.utils.F
将上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_context()
。
- jinja2.evalcontextfunction(f: jinja2.utils.F) jinja2.utils.F
将 eval 上下文作为第一个参数传递给装饰函数。
自 3.0 版起已弃用: 将在 Jinja 3.1 中移除。 请改用
pass_eval_context()
。2.4 版中的新功能。
- jinja2.escape(s)
将字符串 s 中的字符
&
、<
、>
、'
和"
转换为 HTML-安全序列。 如果您需要在 HTML 中显示可能包含此类字符的文本,请使用此选项。 此函数不会转义具有 HTML 表示的对象,例如已经转义的数据。返回值是一个 Markup 字符串。
- jinja2.clear_caches() None
- Jinja 为环境和词法分析器保留内部缓存。 使用这些是为了让 Jinja 不必一直重新创建环境和词法分析器。 通常你不必关心这个,但如果你正在测量内存消耗,你可能想要清理缓存。
- jinja2.is_undefined(obj: Any) bool
检查传递的对象是否未定义。 这只不过是对 Undefined 执行实例检查,但看起来更好。 这可用于想要对未定义变量做出反应的自定义过滤器或测试。 例如,自定义默认过滤器可能如下所示:
- class jinja2.Markup([string])
- classmethod escape(s: Any) markupsafe.Markup
转义字符串。 调用 escape() 并确保为子类返回正确的类型。
- striptags() str
unescape() 标记,删除标签,并将空格规范化为单个空格。
- unescape() str
将转义标记转换回文本字符串。 这将用它们代表的字符替换 HTML 实体。
例外
- exception jinja2.TemplateError(message: Optional[str] = None)
- 所有模板错误的基类。
- exception jinja2.UndefinedError(message: Optional[str] = None)
- 如果模板尝试对 Undefined 进行操作,则会引发。
- exception jinja2.TemplateNotFound(name: Optional[Union[str, Undefined]], message: Optional[str] = None)
如果模板不存在则引发。
在 2.11 版中更改: 如果给定名称为 Undefined 并且未提供任何消息,则会引发 UndefinedError。
- exception jinja2.TemplatesNotFound(names: Sequence[Union[str, Undefined]] = (), message: Optional[str] = None)
像 TemplateNotFound 但如果选择了多个模板,则会引发。 这是 TemplateNotFound 异常的子类,所以只要捕获基本异常就会捕获两者。
在 2.11 版中更改: 如果名称列表中的名称为 Undefined,则会显示有关它未定义的消息而不是空字符串。
2.2 版中的新功能。
- exception jinja2.TemplateSyntaxError(message: str, lineno: int, name: Optional[str] = None, filename: Optional[str] = None)
提出来告诉用户模板有问题。
- message
错误消息为 utf-8 字节串。
- lineno
发生错误的行号
- name
模板的加载名称作为 unicode 字符串。
- filename
将模板加载为文件系统编码中的字节串的文件名(在 Windows 系统上很可能是 utf-8 或 mbcs)。
文件名和错误消息是字节串而不是 unicode 字符串的原因是 Python 2.x 没有将 unicode 用于异常和回溯以及编译器。 这将随着 Python 3 而改变。
- exception jinja2.TemplateAssertionError(message: str, lineno: int, name: Optional[str] = None, filename: Optional[str] = None)
- 类似于模板语法错误,但涵盖了模板中的某些内容在编译时导致错误的情况,而这些错误不一定是由语法错误引起的。 然而,它是 TemplateSyntaxError 的直接子类并且具有相同的属性。
自定义过滤器
自定义过滤器只是常规 Python 函数,它们将过滤器的左侧作为第一个参数,并将传递给过滤器的参数作为额外参数或关键字参数。
例如,在过滤器 模板:42
中,函数将使用 myfilter(42, 23)
调用。 例如,一个简单的过滤器可以应用于日期时间对象来格式化它们:
您可以通过更新环境中的 filters dict 在模板环境中注册它:
在模板内部,它可以按如下方式使用:
过滤器也可以传递当前模板上下文或环境。 如果过滤器想要返回未定义的值或检查当前的 autoescape
设置,这将非常有用。 为此,存在三个装饰器:environmentfilter()、contextfilter() 和 evalcontextfilter()。
这是一个小的示例过滤器,它将文本分成 HTML 换行符和段落,并在启用自动转义时将返回值标记为安全的 HTML 字符串:
上下文过滤器的工作原理相同,只是第一个参数是当前活动的 Context
而不是环境。
评估上下文
评估上下文(短 eval 上下文或 eval ctx)是 Jinja 2.4 中引入的一个新对象,它可以在运行时激活和停用已编译的功能。
目前它仅用于启用和禁用自动转义,但也可用于扩展。
在以前的 Jinja 版本中,过滤器和函数被标记为环境可调用对象,以检查环境中的自动转义状态。 在新版本中,鼓励从评估上下文中检查设置。
之前的版本:
在新版本中,您可以使用 contextfilter() 并从实际上下文访问评估上下文,或者使用 evalcontextfilter() 直接将评估上下文传递给函数:
不得在运行时修改求值上下文。 修改只能发生在扩展的 nodes.EvalContextModifier
和 nodes.ScopedEvalContextModifier
上,而不是在 eval 上下文对象本身上。
- class jinja2.nodes.EvalContext(environment: Environment, template_name: Optional[str] = None)
保存评估时间信息。 自定义属性可以在扩展中附加到它。
- autoescape
True 或 False 取决于自动转义是否处于活动状态。
- volatile
True 如果编译器在编译时无法计算某些表达式。 在运行时,这应该总是 False。
自定义测试
测试就像过滤器一样工作,只是测试无法访问环境或上下文,并且它们无法链接。 测试的返回值应该是 True 或 False。 测试的目的是为模板设计者提供执行类型和一致性检查的可能性。
这是一个简单的测试,用于检查变量是否为素数:
您可以通过更新环境中的 tests dict 在模板环境中注册它:
然后模板设计者可以像这样使用测试:
全局命名空间
存储在 Environment.globals dict 中的变量是特殊的,因为它们也可用于导入的模板,即使它们是在没有上下文的情况下导入的。 您可以在此处放置应始终可用的变量和函数。 此外, Template.globals 存在是可用于特定模板的变量,可用于所有 render() 调用。
低级 API
低级 API 公开了有助于理解一些实现细节、调试目的或高级 扩展 技术的功能。 除非您确切地知道自己在做什么,否则我们不建议您使用其中任何一个。
- Environment.lex(source: str, name: Optional[str] = None, filename: Optional[str] = None) Iterator[Tuple[int, str, str]]
Lex 给定的源代码并返回一个生成器,该生成器以
(lineno, token_type, value)
的形式将标记生成为元组。 这对于 扩展开发 和调试模板很有用。这不执行预处理。 如果要应用扩展的预处理,则必须通过 preprocess() 方法过滤源。
- Environment.parse(source: str, name: Optional[str] = None, filename: Optional[str] = None) jinja2.nodes.Template
解析源代码并返回抽象语法树。 编译器使用此节点树将模板转换为可执行的源代码或字节码。 这对于调试或从模板中提取信息很有用。
如果您正在 开发 Jinja 扩展 ,这将为您提供生成的节点树的良好概览。
- Environment.preprocess(source: str, name: Optional[str] = None, filename: Optional[str] = None) str
- 预处理带有所有扩展名的源。 这对于所有解析和编译方法都会自动调用,但 not 用于 lex(),因为在那里您通常只希望对实际源进行标记化。
- Template.new_context(vars: Optional[Dict[str, Any]] = None, shared: bool = False, locals: Optional[Mapping[str, Any]] = None) jinja2.runtime.Context
为此模板创建一个新的
Context
。 提供的变量将传递给模板。 默认情况下,全局变量被添加到上下文中。 如果 shared 设置为 True,则数据将按原样传递到上下文而不添加全局变量。locals 可以是内部使用的局部变量字典。
- Template.root_render_func(context)
这是低级渲染功能。 它传递了一个
Context
,它必须由相同模板或兼容模板的 new_context() 创建。 此渲染函数由编译器根据模板代码生成,并返回生成 unicode 字符串的生成器。如果模板代码中发生异常,模板引擎不会重写异常而是通过原始异常。 事实上,这个函数只能从 render() / generate() / stream() 调用中调用。
- Template.blocks
- 块渲染函数的字典。 这些函数中的每一个都与 root_render_func() 完全一样,但具有相同的限制。
- Template.is_up_to_date
- 如果有更新版本的模板可用,则此属性为 False,否则为 True。
笔记
低级 API 很脆弱。 未来的 Jinja2 版本将尽量不以向后不兼容的方式对其进行更改,但 Jinja2 核心中的修改可能会大放异彩。 例如,如果 Jinja2 在更高版本中引入了一个新的 AST 节点,该节点可能由 parse() 返回。
元 API
2.2 版中的新功能。
元 API 返回一些有关抽象语法树的信息,这些信息可以帮助应用程序实现更高级的模板概念。 元 API 的所有函数都在 Environment.parse() 方法返回的抽象语法树上运行。
- jinja2.meta.find_undeclared_variables(ast: jinja2.nodes.Template) Set[str]
返回 AST 中所有变量的集合,这些变量将在运行时从上下文中查找。 因为在编译时不知道将根据运行时执行的路径使用哪些变量,所以返回所有变量。
执行
在内部,代码生成器用于查找未声明的变量。 知道这一点很好,因为代码生成器可能会在编译期间引发
TemplateAssertionError
并且事实上该函数当前也可以引发该异常。
- jinja2.meta.find_referenced_templates(ast: jinja2.nodes.Template) Iterator[Optional[str]]
从 AST 中查找所有引用的模板。 这将返回所有硬编码模板扩展、包含和导入的迭代器。 如果使用动态继承或包含,将产生 None。
此功能对于依赖项跟踪很有用。 例如,如果您想在布局模板更改后重建网站的某些部分。