API¶
本文描述的是Jinja的API,而不是模板语言(请参见 模板设计器文档 ). 对于那些实现应用程序的模板接口的人,而不是那些创建Jinja模板的人来说,这将是最有用的参考。
基础¶
Jinja使用一个名为template的中心对象 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
是可导入的,它为您计算出文件夹的绝对路径。
可以使用不同的加载程序以其他方式或从其他位置加载模板。它们列在 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或 develop extensions .
- class 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
如果给定和一个字符串,它将用作基于行的注释的前缀。也见 行语句 .
Changelog
在 2.2 版本加入.
- trim_blocks
如果设置为
True
删除块后的第一个换行符(block,而不是variable tag!)默认为 False .- lstrip_blocks
如果设置为
True
行首空格和制表符从行首剥离到块。默认为 False .- newline_sequence
开始换行的顺序。一定是其中之一
'\r'
,'\n'
或'\r\n'
. 默认值为'\n'
对于Linux和OS X系统以及Web应用程序来说,这是一个有用的默认值。- keep_trailing_newline
呈现模板时保留尾随换行符。默认值为
False
,这将导致从模板结尾剥离一条新行(如果存在)。Changelog
在 2.7 版本加入.
- extensions
要使用的Jinja扩展列表。这可以是作为字符串或扩展类导入路径。有关更多信息,请查看 the extensions documentation .
- optimized
是否应启用优化器?默认是
True
.- undefined
Undefined
或其子类,用于表示模板中未定义的值。- finalize
一种可调用文件,可用于在输出变量表达式之前处理其结果。例如,可以转换
None
在此处隐式转换为空字符串。- autoescape
如果设置为
True
默认情况下,启用XML/HTML自动转义功能。有关自动转义的详细信息,请参阅Markup
. 从Jinja 2.4开始,这也可以是一个可调用的,它传递了模板名,必须返回True
或False
根据自动转义,默认情况下应启用。Changelog
在 2.4 版本发生变更: autoescape 现在可以是函数
- loader
此环境的模板加载器。
- cache_size
缓存的大小。默认情况下,这是
400
这意味着,如果加载的模板超过400个,加载程序将清除最近使用最少的模板。如果缓存大小设置为0
如果缓存大小为-1
不会清除缓存。Changelog
在 2.8 版本发生变更: 缓存大小从低50增加到400。
- auto_reload
一些加载程序从模板源可能更改的位置(例如:文件系统或数据库)加载模板。如果
auto_reload
设置为True
(默认)每次请求模板时,加载程序都会检查源是否更改,如果更改,则加载程序将重新加载模板。为了获得更高的性能,可以禁用它。- bytecode_cache
如果设置为字节码缓存对象,则此对象将为内部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 (BaseLoader | None) --
cache_size (int) --
auto_reload (bool) --
bytecode_cache (BytecodeCache | None) --
enable_async (bool) --
如果模板是通过使用
Template
构造函数自动创建一个环境。这些环境创建为共享环境,这意味着多个模板可能具有相同的匿名环境。对于所有共享环境,此属性是 True ,否则 False .
- sandboxed¶
如果环境是沙盒,则此属性为 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 (BaseLoader | None) --
cache_size (int) --
auto_reload (bool) --
bytecode_cache (BytecodeCache | None) --
enable_async (bool) --
- 返回类型:
- undefined([hint, obj, name, exc])¶
创建新的
Undefined
对象 name . 这对于某些操作可能返回未定义对象的筛选器或函数很有用。除以下参数外的所有参数 hint 应作为关键字参数提供,以提高可读性。这个 hint 如果提供,则用作异常的错误消息,否则将从中生成错误消息 obj 和 name 自动。例外情况如下: exc 如果使用生成的未定义对象执行了未定义对象不允许的操作,则引发。默认的例外是UndefinedError
. 如果A hint 提供了 name 可以省略。创建未定义对象的最常见方法是只提供名称::
return environment.undefined(name='some_name')
这意味着这个名字 some_name 未定义。如果名称来自对象的属性,则有必要告诉未定义的对象holder对象以改进错误消息:
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)¶
在创建环境后添加扩展。
Changelog
在 2.5 版本加入.
- 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
Changelog
在 2.1 版本加入.
- compile_templates(target, extensions=None, filter_func=None, zip='deflated', log_function=None, ignore_errors=True)¶
查找加载程序可以找到的所有模板,编译它们并将其存储在 target . 如果 zip 是 None 而不是压缩文件,模板将存储在一个目录中。默认情况下,使用放气zip算法。要切换到存储的算法, zip 可以设置为
'stored'
.extensions 和 filter_func 被传递给
list_templates()
. 返回的每个模板都将编译到目标文件夹或zipfile中。默认情况下,模板编译错误被忽略。如果提供了日志函数,则会记录错误。如果希望模板语法错误中止编译,可以设置 ignore_errors 到 False 您将得到一个语法错误的异常。
Changelog
在 2.4 版本加入.
- extend(**attributes)¶
如果这些项尚不存在,请将它们添加到环境实例中。这是由 extensions 注册回调和配置值而不破坏继承。
- 参数:
attributes (Any) --
- 返回类型:
None
- from_string(source, globals=None, template_class=None)¶
从源字符串加载模板,而不使用
loader
。
- get_or_select_template(template_name_or_list, parent=None, globals=None)¶
使用
select_template()
如果给出了模板名称的可迭代数,或者get_template()
如果只给出一个名字的话。Changelog
在 2.3 版本加入.
- 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
这些额外变量可用于该模板的所有渲染。如果模板已经加载和缓存,则它的全局变量将使用任何新项目进行更新。
- 返回类型:
Changelog
在 3.0 版本发生变更: 如果从高速缓存加载模板,
globals
将更新模板的全局值,而不是忽略新值。在 2.4 版本发生变更: 如果
name
是一种Template
对象,则原封不动地返回。
- join_path(template, parent)¶
将模板与父模板联接。默认情况下,所有查找都是相对于加载器根目录的,因此此方法返回 template 参数不变,但如果路径应该相对于父模板,则可以使用此函数计算实际模板名称。
子类可以重写此方法并在此处实现模板路径连接。
- list_templates(extensions=None, filter_func=None)¶
返回此环境的模板列表。这要求加载器支持加载器的
list_templates()
方法。如果模板文件夹中除实际模板外还有其他文件,则可以过滤返回的列表。有两种方法:要么 extensions 设置为模板的文件扩展名列表,或 filter_func 可以提供,它是一个可调用的,传递模板名并应返回 True 如果它最终出现在结果列表中。
如果加载器不支持,a
TypeError
提高了。Changelog
在 2.4 版本加入.
- select_template(names, parent=None, globals=None)¶
喜欢
get_template()
,但尝试加载多个名称。如果所有名称都不能加载到TemplatesNotFound
引发异常。- 参数:
parent (str | None) -- 导入此模板的父模板的名称。
join_path()
可以用来实现名称转换。globals (MutableMapping[str, Any] | None) -- 扩展环境
globals
这些额外变量可用于该模板的所有渲染。如果模板已经加载和缓存,则它的全局变量将使用任何新项目进行更新。
- 返回类型:
Changelog
在 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
。使用相同的环境参数创建的所有模板共享相同的临时模板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 (bool) --
- 返回类型:
- globals¶
每次呈现模板时可用的变量字典,而不需要在呈现过程中传递它们。这不应修改,因为它可能与环境和其他模板共享,具体取决于模板的加载方式。
默认为
Environment.globals
除非将额外的值传递给Environment.get_template()
。全局变量仅适用于模板的每次呈现都通用的数据。应将特定数据传递给
render()
。看见 超空间 。
- name¶
模板的加载名称。如果从字符串加载模板,则 None .
- filename¶
文件系统上模板的文件名(如果从中加载)。否则这是 None .
- render([context])¶
此方法接受与 dict 构造器:dict、dict子类或一些关键字参数。如果没有提供参数,则上下文将为空。这两个电话的作用相同:
template.render(knights='that say nih') template.render({'knights': 'that say nih'})
这将以字符串形式返回呈现的模板。
- generate([context])¶
对于非常大的模板,不要一次呈现整个模板,而是逐个计算每个语句并逐个生成结果,这可能很有用。此方法基本上就是这样做的,并返回一个生成器,该生成器以字符串的形式生成一个接一个的项目。
它接受与
render()
.
- stream([context])¶
工作原理和
generate()
但返回ATemplateStream
.- 参数:
- 返回类型:
- async render_async([context])¶
这项工作类似于
render()
但返回一个协程,在等待时返回整个呈现的模板字符串。这需要启用异步功能。示例用法:
await template.render_async(knights='that say nih; asynchronously')
- async generate_async([context])¶
的异步版本
generate()
. 工作原理非常相似,但返回异步迭代器。- 参数:
- 返回类型:
- 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将大模板流式传输到客户端,这主要是有用的。
- disable_buffering()¶
禁用输出缓冲。
- 返回类型:
None
- dump(fp, encoding=None, errors='strict')¶
将整个流转储到文件或类似文件的对象中。根据默认字符串写入,如果要在写入之前进行编码,请指定 encoding 。
示例用法:
Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
自动逃逸¶
Changelog
在 2.4 版本发生变更.
Jinja现在提供了自动转义支持。从jinja2.9开始,autoescape扩展被删除并内置。不过,自动转义在默认情况下还没有启用,不过这很可能在将来发生变化。建议为自动转义配置一个合理的默认值。这使得可以在每个模板的基础上启用和禁用自动转义(例如,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 .
出于安全原因,此函数不区分大小写。
Changelog
在 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
- 参数:
hint (str | None) --
obj (Any) --
name (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
Changelog
在 2.11.0 版本加入.
- 参数:
hint (str | None) --
obj (Any) --
name (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
- 参数:
hint (str | None) --
obj (Any) --
name (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
- 参数:
hint (str | None) --
obj (Any) --
name (str | None) --
exc (Type[TemplateRuntimeError]) --
还有一个工厂函数可以修饰未定义的对象以实现登录失败:
- jinja2.make_logging_undefined(logger=None, base=<class 'jinja2.runtime.Undefined'>)¶
给定logger对象,这将返回一个新的未定义类,该类将记录某些失败。它将记录迭代和打印。如果没有给定记录器,则创建默认记录器。
例子::
logger = logging.getLogger(__name__) LoggingUndefined = make_logging_undefined( logger=logger, base=Undefined )
Changelog
在 2.8 版本加入.
未定义的对象是通过调用 undefined
.
实施
Undefined
重写由 __underscore__
方法。例如默认值 Undefined
类实现 __str__
返回一个空字符串,而 __int__
其他人则例外地失败了。通过返回 0
你可以实现你自己的子类。
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¶
模板上下文保存模板的变量。它存储传递给模板的值以及模板导出的名称。创建实例既不受支持也不有用,因为它是在模板评估的各个阶段自动创建的,不应该手工创建。
The context is immutable. Modifications on
parent
must not happen and modifications onvars
are allowed from generated template code only. Template filters and global functions marked aspass_context()
get the active context passed as first argument and are allowed to access the context read-only.模板上下文支持只读dict操作 (get, keys, values, items, iterkeys, itervalues, iteritems, _ _getitem__, __contains__ )另外还有一个
resolve()
方法不会失败 KeyError 但是返回Undefined
缺少变量的对象。- 参数:
- parent¶
模板查找的只读全局变量的dict。这些要么来自另一个
Context
,从Environment.globals
或Template.globals
或者指向通过将全局变量与传递给呈现函数的变量组合而创建的dict。不得更改。
- environment¶
加载模板的环境。
- exported_vars¶
此集合包含模板导出的所有名称。名称的值位于
vars
dict.为了得到导出变量的dict副本,get_exported()
可以使用。
- name¶
拥有此上下文的模板的加载名称。
- blocks¶
模板中块的当前映射的dict。此dict中的键是块的名称,值是已注册的块列表。每个列表中的最后一项是当前活动块(继承链中最新的)。
- call(callable, \*args, \**kwargs)¶
使用提供的参数和关键字参数调用Callable,但如果Callable具有
pass_context()
或pass_environment()
。
- get(key, default=None)¶
按名称查找变量,如果找不到键,则返回缺省值。
- resolve(key)¶
按名称查找变量,或返回
Undefined
如果找不到密钥,则返回。如果需要添加自定义行为,请重写
resolve_or_missing()
,而不是这种方法。各种查找函数都使用该方法,而不是此方法。
上下文是不变的,它阻止修改,如果以某种方式修改了它,尽管这些更改可能不会显示出来。为了提高性能,JJJA不使用上下文作为的数据存储,只将其作为主数据源。模板未定义的变量在上下文中查找,但模板定义的变量存储在本地。
函数不应该直接修改上下文,而应该返回一个可以赋值给模板本身内的变量的值。
{% 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提供的内置装载机列表:
- class jinja2.FileSystemLoader(searchpath, encoding='utf-8', followlinks=False)¶
从文件系统中的目录加载模板。
路径可以是相对路径,也可以是绝对路径。相对路径相对于当前工作目录。
loader = FileSystemLoader("templates")
可以给出路径列表。将按顺序搜索目录,并在第一个匹配的模板处停止。
loader = FileSystemLoader(["/override/templates", "/default/templates"])
- 参数:
Changelog
在 2.8 版本发生变更: 添加了
followlinks
参数。
- class jinja2.PackageLoader(package_name, package_path='templates', encoding='utf-8')¶
从Python包中的目录加载模板。
- 参数:
下面的示例在
pages
目录中的project.ui
包裹。loader = PackageLoader("project.ui", "pages")
仅支持作为目录(标准pip行为)或zip/egg文件(不太常见)安装的软件包。用于内省包中数据的Python API太有限,无法支持此加载器所需的其他安装方法。
对以下项目的支持有限 PEP 420 命名空间包。假定模板目录仅位于一个命名空间贡献器中。不支持对命名空间有贡献的ZIP文件。
Changelog
在 3.0 版本发生变更: 不再使用
setuptools
作为一种依赖。在 3.0 版本发生变更: 有限的PEP 420命名空间包支持。
- class jinja2.DictLoader(mapping)¶
从将模板名称映射到模板源的Python字典加载模板。此加载器对于单元测试非常有用:
>>> loader = DictLoader({'index.html': 'source here'})
因为自动重新加载很少有用,所以在默认情况下禁用。
- class jinja2.FunctionLoader(load_func)¶
向其传递执行加载的函数的加载器。该函数接收模板的名称,并且必须返回包含模板源的字符串或形式的元组
(source, filename, uptodatefunc)
或 None 如果模板不存在。>>> def load_template(name): ... if name == 'index.html': ... return '...' ... >>> loader = FunctionLoader(load_template)
这个 uptodatefunc 是一个函数,如果启用了autoreload并且必须返回 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]) --
字节码缓存¶
Jinja2.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)
jinteja是一个更高级的基于字节缓存的文件系统版本。
- clear()¶
清除缓存。Jinja不使用此方法,但应实现该方法以允许应用程序清除特定环境使用的字节码缓存。
- 返回类型:
None
- class jinja2.bccache.Bucket(environment, key, checksum)¶
存储桶用于存储一个模板的字节码。它由字节码缓存创建和初始化,并传递给加载函数。
Buckets从分配的缓存中获取内部校验和,并使用该校验和自动拒绝过期的缓存材料。单独的字节码缓存子类不必关心缓存的无效性。
- 参数:
environment (Environment) --
key (str) --
checksum (str) --
- environment¶
这个
Environment
创造了这个桶。
- key¶
此bucket的唯一缓存密钥
- code¶
如果加载了字节码,则返回字节码,否则 None .
- reset()¶
重置存储桶(卸载字节码)。
- 返回类型:
None
内置字节码缓存:
- class jinja2.FileSystemBytecodeCache(directory=None, pattern='__jinja2_%s.cache')¶
在文件系统上存储字节码的字节码缓存。它接受两个参数:存储缓存项的目录和用于构建文件名的模式字符串。
如果未指定目录,则选择默认缓存目录。在Windows上,使用用户的临时目录,在UNIX系统上,在系统临时目录中为用户创建一个目录。
该模式可用于在同一目录上运行多个单独的缓存。默认模式是
'__jinja2_%s.cache'
.%s
替换为缓存键。>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
这个字节码缓存支持使用clear方法清除缓存。
- class jinja2.MemcachedBytecodeCache(client, prefix='jinja2/bytecode/', timeout=None, ignore_memcache_errors=True)¶
此类实现使用memcache缓存来存储信息的字节码缓存。它不强制执行特定的memcache库(tummy的memcache或cmemcache),但将接受提供所需最小接口的任何类。
与此类兼容的库:
(不幸的是,Django缓存接口不兼容,因为它不支持存储二进制数据,只支持文本。但是,您可以将底层缓存客户端传递到字节码缓存,该缓存可作为 django.core.cache.cache._client 。)
传递给构造函数的客户端的最小接口是:
- 参数:
- class MinimalClientInterface¶
- set(key, value[, timeout])¶
value 是一个字符串 timeout 键的超时。如果未提供超时,则应假定为默认超时或不超时;如果提供超时,则应假定为一个整数,其中包含缓存项应存在的秒数。
- get(key)¶
返回缓存键的值。如果缓存中不存在该项,则返回值必须为 None .
构造函数的其他参数是在实际缓存键之前添加的所有键的前缀,以及缓存系统中字节码的超时。我们建议高(或无)超时。
此字节码缓存不支持清除缓存中的已用项。clear方法是一个无操作函数。
Changelog
在 2.7 版本加入: 增加了对忽略memcache错误的支持 ignore_memcache_errors 参数。
异步支持¶
Changelog
在 2.9 版本加入.
Jinja支持Python async
和 await
语法。对于模板设计器,此支持(启用时)是完全透明的,模板看起来仍然完全相同。但是,开发人员应该了解实现,因为它会影响您可以使用的api类型。
默认情况下,异步支持被禁用。启用它将导致环境在幕后编译不同的代码,以便在异步事件循环中处理异步和同步代码。这有以下含义:
模板呈现要求事件循环对当前线程可用。
asyncio.get_running_loop()
必须返回事件循环。编译后的代码使用
await
用于函数和属性,并使用async for
循环。为了支持在此上下文中同时使用异步和同步函数,在所有调用和访问周围放置了一个小包装器,与纯粹的异步代码相比,这增加了开销。同步方法和过滤器在需要的地方成为其相应异步实现的包装器。例如,
render
调用async_render
和|map
支持异步iterables。
可等待的对象可以从模板中的函数返回,模板中的任何函数调用都将自动等待结果。这个 await
通常情况下,Python是隐含的。例如,您可以提供一个从数据库异步加载数据的方法,从模板设计器的角度来看,可以像调用任何其他函数一样调用它。
政策¶
从Jinja 2.9开始,可以在环境中配置策略,这对过滤器和其他模板构造的行为有轻微影响。它们可以配置为 policies
属性。
例子::
env.policies['urlize.rel'] = 'nofollow noopener'
truncate.leeway
:为配置leeway默认值 truncate 过滤器。2.9中介绍的leeway,但为了恢复与旧模板的兼容性,可以将其配置为 0 把以前的行为恢复过来。默认值为 5 .
urlize.rel
:一个字符串,用于定义 rel 生成的链接的属性 urlize 过滤器。始终添加这些项目。默认值为 noopener .
urlize.target
:为来自的链接发出的默认目标 urlize 如果调用未显式定义其他目标,则筛选。
urlize.extra_schemes
:识别除默认方案之外还以这些方案开头的URL
http://
,https://
,以及mailto:
。json.dumps_function
:如果将此值设置为 None 然后 tojson 过滤器将使用此函数而不是默认函数进行转储。注意,这个函数应该接受将来可能从过滤器传递的任意额外参数。当前唯一可以传递的参数是 indent . 默认转储函数为
json.dumps
.json.dumps_kwargs
:要传递给dump函数的关键字参数。默认值为
{{'sort_keys': True}}
.
ext.i18n.trimmed
:如果设置为 True ,
{{% trans %}}
街区 i18n扩展 将始终统一换行符和周围空白,就像 trimmed 使用了修饰符。
公用事业¶
如果您向Jinja环境添加自定义过滤器或函数,这些helper函数和类非常有用。
- jinja2.pass_context(f)¶
将
Context
作为呈现模板时调用的修饰函数的第一个参数。可用于函数、筛选器和测试。
要是
Context.eval_context
需要时,请使用pass_eval_context()
。要是Context.environment
需要时,请使用pass_environment()
。Changelog
在 3.0.0 版本加入: 取代
contextfunction
和contextfilter
。- 参数:
f (F) --
- 返回类型:
F
- jinja2.pass_eval_context(f)¶
将
EvalContext
作为呈现模板时调用的修饰函数的第一个参数。看见 评估背景 。可用于函数、筛选器和测试。
要是
EvalContext.environment
需要时,请使用pass_environment()
。Changelog
在 3.0.0 版本加入: 取代
evalcontextfunction
和evalcontextfilter
。- 参数:
f (F) --
- 返回类型:
F
- jinja2.pass_environment(f)¶
将
Environment
作为呈现模板时调用的修饰函数的第一个参数。可用于函数、筛选器和测试。
Changelog
在 3.0.0 版本加入: 取代
environmentfunction
和environmentfilter
。- 参数:
f (F) --
- 返回类型:
F
- jinja2.clear_caches()¶
Jinja为环境和lexer保留内部缓存。这些都是为了使Jinja不必一直重新创建环境和Lexer。通常情况下,您不必关心这一点,但如果您正在测量内存消耗,您可能需要清理缓存。
- 返回类型:
None
例外情况¶
- exception jinja2.UndefinedError(message=None)¶
在模板尝试操作时引发
Undefined
.- 参数:
message (str | None) --
- 返回类型:
None
- exception jinja2.TemplateNotFound(name, message=None)¶
如果模板不存在则引发。
Changelog
在 2.11 版本发生变更: 如果名字是
Undefined
但没有提供任何信息UndefinedError
提高了。
- exception jinja2.TemplatesNotFound(names=(), message=None)¶
喜欢
TemplateNotFound
TemplateNotFound
异常,因此只捕获基本异常将同时捕获这两个异常。
- exception jinja2.TemplateSyntaxError(message, lineno, name=None, filename=None)¶
引发以告诉用户模板有问题。
- message¶
错误消息。
- lineno¶
发生错误的行号。
- name¶
模板的加载名称。
- filename¶
以文件系统编码方式加载模板的文件名(很可能是utf-8,或Windows系统上的mbcs)。
自定义过滤器¶
筛选器是将筛选器左侧的值作为第一个参数并生成新值的Python函数。传递给筛选器的参数在值之后传递。
例如,过滤器 {{ 42|myfilter(23) }}
在幕后被调用为 myfilter(42, 23)
。
Jinja自带了一些 built-in filters 。若要使用自定义筛选器,请编写一个函数,该函数至少接受 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") }}
有些装饰器可以告诉JJJA将额外的信息传递给过滤器。该对象作为第一个参数传递,使被筛选的值成为第二个参数。
pass_context()
传递当前Context
。
下面是一个将换行符转换为HTML的过滤器 <br>
和 <p>
标签。在转义输入并将输出标记为安全之前,它使用val上下文检查当前是否启用了自动转义。
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
自定义测试¶
测试是将测试左侧的值作为第一个参数并返回 True
或 False
。传递给测试的参数在值之后传递。
例如,测试 {{ 42 is even }}
在幕后被调用为 is_even(42)
。
Jinja自带了一些 built-in tests 。若要使用自定义测试,请编写一个函数,该函数至少接受 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 %}
一些装饰者可以告诉JJUA将额外的信息传递给测试。该对象作为第一个参数传递,使被测试值成为第二个参数。
pass_context()
传递当前Context
。
评估背景¶
使用求值上下文(简短的评测上下文或评测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的全局变量 b.render()
。
加载任何模板后不能更改环境全局变量,加载模板后任何时候都不能更改模板全局变量。加载模板后更改全局变量将导致意外行为,因为它们可能在环境和其他模板之间共享。
低层API¶
低级API公开了一些功能,这些功能对于理解一些实现细节、调试目的或高级功能很有用。 extension 技术。除非你确切知道你在做什么,否则我们不建议你使用这些。
- Environment.lex(source, name=None, filename=None)¶
lex给定的源代码并返回一个生成器,该生成器以元组的形式生成令牌
(lineno, token_type, value)
. 这对 extension development 以及调试模板。这不执行预处理。如果要应用扩展的预处理,则必须通过
preprocess()
方法。
- Environment.parse(source, name=None, filename=None)¶
分析源代码并返回抽象语法树。编译器使用此节点树将模板转换为可执行源代码或字节码。这对于调试或从模板中提取信息很有用。
如果你是 developing Jinja extensions 这可以很好地概述生成的节点树。
- Environment.preprocess(source, name=None, filename=None)¶
用所有扩展名预处理源。对于所有的解析和编译方法都会自动调用此函数,但是 not 对于
lex()
因为在那里,您通常只希望对实际的源进行标记化。
- Template.new_context(vars=None, shared=False, locals=None)¶
创建新的
Context
对于此模板。提供的var将传递到模板。默认情况下,全局变量被添加到上下文中。如果“共享”设置为 True 数据按原样传递到上下文,而不添加全局变量。locals 可以是局部变量的dict以供内部使用。
- 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¶
Changelog
在 2.2 版本加入.
metaAPI返回一些抽象语法树的信息,这些信息可以帮助应用程序实现更高级的模板概念。meta 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]
此函数对于依赖项跟踪很有用。例如,如果要在布局模板更改后重建网站的部分内容。