API

本文档描述了Jinja2的API,而不是模板语言。对于那些将模板接口实现到应用程序的人,而不是那些正在创建jinja2模板的人来说,这将是最有用的参考。

基础

jinja2使用一个称为模板的中心对象 Environment . 此类的实例用于存储配置和全局对象,并用于从文件系统或其他位置加载模板。即使使用的构造函数从字符串创建模板, Template 类,将自动为您创建一个环境,尽管是共享的环境。

大多数应用程序将创建一个 Environment 应用程序初始化时的对象,并使用该对象加载模板。但是,在某些情况下,如果使用不同的配置,那么并排拥有多个环境是很有用的。

配置jinja2为应用程序加载模板的最简单方法大致如下:

from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
    loader=PackageLoader('yourapplication', 'templates'),
    autoescape=select_autoescape(['html', 'xml'])
)

这将创建一个具有默认设置的模板环境,以及一个在 templates 文件夹 yourapplication python包。可以使用不同的加载程序,如果要从数据库或其他资源加载模板,也可以编写自己的加载程序。这还支持HTML和XML文件的自动转义。

要从该环境加载模板,只需调用 get_template() 方法,然后返回加载的 Template ::

template = env.get_template('mytemplate.html')

要用一些变量呈现它,只需调用 render() 方法:

print template.render(the='variables', go='here')

使用模板加载程序而不是将字符串传递给 TemplateEnvironment.from_string() 具有多种优势。除了更容易使用外,它还支持模板继承。

自动转义的注意事项

在未来版本的jinja2中,出于安全原因,我们可能默认启用自动转义。因此,我们鼓励您现在显式地配置自动转义,而不是依赖默认值。

统一码

Jinja2在内部使用Unicode,这意味着您必须将Unicode对象传递给只包含ASCII字符的呈现函数或字节字符串。此外,换行符被规范化为每种默认的Unix样式的一个行尾序列。 (\n

python 2.x支持两种表示字符串对象的方法。一个是 str 类型,另一个是 unicode 类型,这两个类型都扩展名为 basestring . 不幸的是,违约是 str 除非只使用ASCII字符,否则不应将其用于存储基于文本的信息。使用python 2.6可以 unicode 每个模块级别的默认值,对于python 3,它将是默认值。

要显式使用Unicode字符串,必须在字符串文字前面加上 uu'Hänsel und Gretel sagen Hallo' . 这样,通过使用当前python模块中的字符编码对字符串进行解码,python将字符串存储为unicode。如果未指定编码,则默认为“ascii”,这意味着您不能使用任何非ascii标识符。

要设置更好的模块编码,请使用unicode文本将以下注释添加到python模块的第一行或第二行:

# -*- coding: utf-8 -*-

我们建议将UTF-8作为Python模块和模板的编码,因为它可以用UTF-8表示每个Unicode字符,并且因为它向后兼容于ASCII。对于jinja2,模板的默认编码假定为utf-8。

不能使用jinja2处理非Unicode数据。原因是jinja2已经在语言级别上使用了unicode。例如,jinja2将非中断空格视为表达式中的有效空白,因为表达式需要了解编码或操作Unicode字符串的知识。

有关Python中Unicode的更多详细信息,请查看 Unicode documentation .

另一件重要的事情是Jinja2如何处理模板中的字符串文本。一个幼稚的实现将对所有字符串文本使用Unicode字符串,但在过去,这是有问题的,因为有些库正在对其进行类型检查 str 明确地。例如 datetime.strftime 不接受Unicode参数。为了不把它完全弄坏,Jinja2回来了 str 对于适合ASCII的字符串和其他所有字符串 unicode

>>> m = Template(u"{% set a, b = 'foo', 'föö' %}").module
>>> m.a
'foo'
>>> m.b
u'f\xf6\xf6'

高级API

高级API是应用程序中用于加载和呈现Jinja2模板的API。这个 低层API 另一方面,只有当你想深入了解Jinja2或 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

如果给定和一个字符串,它将用作基于行的注释的前缀。也见 行语句 .

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 ,这将导致从模板结尾剥离一条新行(如果存在)。

2.7 新版功能.

extensions

要使用的Jinja扩展列表。这可以是作为字符串或扩展类导入路径。有关更多信息,请查看 the extensions documentation .

optimized

是否应启用优化器?默认是 True .

undefined

Undefined 或其子类,用于表示模板中未定义的值。

finalize

一种可调用文件,可用于在输出变量表达式之前处理其结果。例如,可以转换 None 在此处隐式转换为空字符串。

autoescape

如果设置为 True 默认情况下,启用XML/HTML自动转义功能。有关自动转义的详细信息,请参阅 Markup . 从Jinja 2.4开始,这也可以是一个可调用的,它传递了模板名,必须返回 TrueFalse 根据自动转义,默认情况下应启用。

在 2.4 版更改: autoescape 现在可以是函数

loader

此环境的模板加载器。

cache_size

缓存的大小。默认情况下,这是 400 这意味着,如果加载的模板超过400个,加载程序将清除最近使用最少的模板。如果缓存大小设置为 0 如果缓存大小为 -1 不会清除缓存。

在 2.8 版更改: 缓存大小从低50增加到400。

auto_reload

一些加载程序从模板源可能更改的位置(例如:文件系统或数据库)加载模板。如果 auto_reload 设置为 True (默认)每次请求模板时,加载程序都会检查源是否更改,如果更改,则加载程序将重新加载模板。为了获得更高的性能,可以禁用它。

bytecode_cache

如果设置为字节码缓存对象,则此对象将为内部Jinja字节码提供缓存,以便在不更改模板的情况下不必解析模板。

字节码缓存 更多信息。

enable_async

如果设置为true,这将启用异步模板执行,允许您利用更新的python功能。这需要python 3.6或更高版本。

shared

如果模板是通过使用 Template 构造函数自动创建一个环境。这些环境创建为共享环境,这意味着多个模板可能具有相同的匿名环境。对于所有共享环境,此属性是 True ,否则 False .

sandboxed

如果环境是沙盒,则此属性为 True . 对于沙盒模式,请查看 SandboxedEnvironment .

filters

此环境的筛选器字典。只要没有加载模板,就可以安全地添加新的筛选器或删除旧的。有关自定义筛选器,请参见 自定义过滤器 . 对于有效的过滤器名称,请查看 标识符说明 .

tests

此环境的测试函数的dict。只要没有加载模板,就可以安全地修改此dict。有关自定义测试,请参见 自定义测试 . 对于有效的测试名称,请查看 标识符说明 .

globals

全局变量的字典。这些变量在模板中始终可用。只要没有加载模板,就可以安全地修改此dict。有关详细信息,请参阅 超空间 . 对于有效的对象名称,请查看 标识符说明 .

policies

一本字典 政策 . 这些可以重新配置以更改运行时行为或某些模板功能。通常这些都与安全相关。

code_generator_class

用于代码生成的类。在大多数情况下,这不应该更改,除非您需要修改模板编译到的Python代码。

context_class

用于模板的上下文。在大多数情况下,这不应该更改,除非您需要修改模板变量如何处理的内部。有关详细信息,请参阅 Context .

overlay([options])

创建一个新的覆盖环境,该环境与当前环境共享除缓存和重写属性之外的所有数据。无法删除覆盖环境的扩展名。覆盖的环境会自动获取它所链接环境的所有扩展以及可选的额外扩展。

创建覆盖应该在初始环境完全设置之后进行。并不是所有的属性都是真正链接的,有些属性只是复制过来的,所以对原始环境的修改可能不会发光。

undefined([hint, obj, name, exc])

创建新的 Undefined 对象 name . 这对于某些操作可能返回未定义对象的筛选器或函数很有用。除以下参数外的所有参数 hint 应作为关键字参数提供,以提高可读性。这个 hint 如果提供,则用作异常的错误消息,否则将从中生成错误消息 objname 自动。例外情况如下: 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')

如果它 nameobj 是已知的(例如,因为访问了属性),即使自定义 hint 提供。这使未定义的对象有可能增强错误消息。

add_extension(extension)

在创建环境后添加扩展。

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_noneFalse .

>>> env.compile_expression('var')() is None
True
>>> env.compile_expression('var', undefined_to_none=False)()
Undefined

2.1 新版功能.

compile_templates(target, extensions=None, filter_func=None, zip='deflated', log_function=None, ignore_errors=True, py_compile=False)

查找加载程序可以找到的所有模板,编译它们并将其存储在 target . 如果 zipNone 而不是压缩文件,模板将存储在一个目录中。默认情况下,使用放气zip算法。要切换到存储的算法, zip 可以设置为 'stored' .

extensionsfilter_func 被传递给 list_templates() . 返回的每个模板都将编译到目标文件夹或zipfile中。

默认情况下,模板编译错误被忽略。如果提供了日志函数,则会记录错误。如果希望模板语法错误中止编译,可以设置 ignore_errorsFalse 您将得到一个语法错误的异常。

如果 py_compile 设置为 True .pyc文件将写入目标,而不是标准的.py文件。这个标志对pypy和python 3没有任何作用,其中pyc文件本身不会被提取,也不会带来太大的好处。

2.4 新版功能.

extend(**attributes)

如果这些项尚不存在,请将它们添加到环境实例中。这是由 extensions 注册回调和配置值而不破坏继承。

from_string(source, globals=None, template_class=None)

从字符串加载模板。这将解析给定的源并返回 Template 对象。

get_or_select_template(template_name_or_list, parent=None, globals=None)

排版和发送到 select_template() 如果给定了模板名称的可ITable,则为 get_template() .

2.3 新版功能.

get_template(name, parent=None, globals=None)

从加载程序加载模板。如果配置了加载程序,此方法将向加载程序请求模板并返回 Template . 如果 parent 参数不是 Nonejoin_path() 在加载前调用以获取真正的模板名。

这个 globals 参数可用于提供模板范围的全局参数。这些变量在渲染时在上下文中可用。

如果模板不存在 TemplateNotFound 引发异常。

在 2.4 版更改: 如果 name 是一个 Template 对象,它从函数中返回,未更改。

join_path(template, parent)

将模板与父模板联接。默认情况下,所有查找都是相对于加载器根目录的,因此此方法返回 template 参数不变,但如果路径应该相对于父模板,则可以使用此函数计算实际模板名称。

子类可以重写此方法并在此处实现模板路径连接。

list_templates(extensions=None, filter_func=None)

返回此环境的模板列表。这要求加载器支持加载器的 list_templates() 方法。

如果模板文件夹中除实际模板外还有其他文件,则可以过滤返回的列表。有两种方法:要么 extensions 设置为模板的文件扩展名列表,或 filter_func 可以提供,它是一个可调用的,传递模板名并应返回 True 如果它最终出现在结果列表中。

如果加载器不支持,a TypeError 提高了。

2.4 新版功能.

select_template(names, parent=None, globals=None)

工作原理类似 get_template() 但在失败之前尝试了许多模板。如果找不到任何模板,它将引发 TemplatesNotFound 例外。

2.3 新版功能.

在 2.4 版更改: 如果 names 包含一个 Template 对象,它从函数中返回,未更改。

class jinja2.Template

中心模板对象。此类表示已编译的模板,并用于对其进行计算。

通常,模板对象是从 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
globals

带有该模板全局值的dict。修改此dict是不安全的,因为它可能与其他模板或加载模板的环境共享。

name

模板的加载名称。如果从字符串加载模板,则 None .

filename

文件系统上模板的文件名(如果从中加载)。否则这是 None .

render([context])

此方法接受与 dict 构造器:dict、dict子类或一些关键字参数。如果没有提供参数,则上下文将为空。这两个电话的作用相同:

template.render(knights='that say nih')
template.render({'knights': 'that say nih'})

这将以unicode字符串的形式返回呈现的模板。

generate([context])

对于非常大的模板,不要一次呈现整个模板,而是一个接一个地评估每个语句,并逐段生成。此方法基本上就是这样做的,并返回一个生成器,该生成器以Unicode字符串的形式生成一个接一个项。

它接受与 render() .

stream([context])

工作原理和 generate() 但返回A TemplateStream .

render_async([context])

这项工作类似于 render() 但返回一个协程,在等待时返回整个呈现的模板字符串。这需要启用异步功能。

示例用法:

await template.render_async(knights='that say nih; asynchronously')
generate_async([context])

的异步版本 generate() . 工作原理非常相似,但返回异步迭代器。

make_module(vars=None, shared=False, locals=None)

这种方法的工作原理与 module 属性在没有参数的情况下调用,但它将在每次调用时评估模板,而不是缓存模板。还可以提供一个dict,然后将其用作上下文。参数与 new_context() 方法。

module

模板作为模块。这用于模板运行时中的导入,但如果要访问从python层导出的模板变量,这也很有用:

>>> t = Template('{% macro foo() %}42{% endmacro %}23')
>>> str(t.module)
'23'
>>> t.module.foo() == u'42'
True

如果启用异步模式,则此属性不可用。

class jinja2.environment.TemplateStream

模板流的工作方式与普通的Python生成器非常相似,但它可以缓冲多个项目以减少总迭代次数。默认情况下,输出是未缓冲的,这意味着对于模板中的每个未缓冲指令,都会生成一个Unicode字符串。

如果启用缓冲区,缓冲区大小为5,则将五个项目组合成新的Unicode字符串。如果您通过wsgi将大模板流式传输到客户机,这一点非常有用,因为wsgi会在每次迭代后刷新。

disable_buffering()

禁用输出缓冲。

dump(fp, encoding=None, errors='strict')

将整个流转储到文件或类似文件的对象中。如果要在写入之前进行编码,则按照默认的Unicode字符串写入 encoding .

示例用法:

Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
enable_buffering(size=5)

启用缓冲。缓冲区 size 在生产之前。

自动逃逸

在 2.4 版更改.

Jinja2现在提供自动逃逸支持。自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 新版功能.

这里是一个建议的设置,它为以 '.html''.htm''.xml' 默认情况下,对所有其他扩展都禁用它。你可以使用 select_autoescape() 功能:

from jinja2 import Environment, 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 块(见) 自动转义重写

标识符说明

jinja2使用常规的python 2.x命名规则。有效标识符必须匹配 [a-zA-Z_][a-zA-Z0-9_]* . 事实上,目前不允许使用非ASCII字符。一旦为python 3完全指定了unicode标识符,这种限制可能就会消失。

在单独的名称空间中查找过滤器和测试,并稍微修改了标识符语法。过滤器和测试可能包含点,用于按主题对过滤器和测试进行分组。例如,在filter dict中添加一个函数并调用它是完全有效的 to.unicode . 筛选器和测试标识符的正则表达式是 [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)* '.

未定义类型

这些类可以用作未定义的类型。这个 Environment 构造函数接受 undefined 参数,可以是这些类之一,也可以是 Undefined . 每当模板引擎无法查找名称或访问属性时,就会创建并返回其中一个对象。然后允许对未定义的值执行某些操作,其他操作失败。

最接近常规的python行为是 StrictUndefined 如果它是未定义的对象,则不允许测试之外的所有操作。

class jinja2.Undefined

默认的未定义类型。这个未定义的类型可以被打印和迭代,但其他每个访问都将引发 jinja2.exceptions.UndefinedError

>>> foo = Undefined(name='foo')
>>> str(foo)
''
>>> not foo
True
>>> foo + 42
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined
_undefined_hint

要么 None 或包含未定义对象错误消息的Unicode字符串。

_undefined_obj

要么 None 或导致创建未定义对象的所有者对象(例如,因为属性不存在)。

_undefined_name

未定义的变量/属性的名称或 None 如果不存在此类信息。

_undefined_exception

未定义对象要引发的异常。这通常是 UndefinedErrorSecurityError .

_fail_with_undefined_error(*args, **kwargs)

当用任何参数调用时,此方法引发 _undefined_exception 从存储在未定义对象上的未定义提示生成错误消息。

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
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

还有一个工厂函数可以修饰未定义的对象以实现登录失败:

jinja2.make_logging_undefined(logger=None, base=None)

给定logger对象,这将返回一个新的未定义类,该类将记录某些失败。它将记录迭代和打印。如果没有给定记录器,则创建默认记录器。

例子::

logger = logging.getLogger(__name__)
LoggingUndefined = make_logging_undefined(
    logger=logger,
    base=Undefined
)

2.8 新版功能.

参数
  • logger -- 要使用的记录器。如果未提供,将创建默认记录器。

  • base -- 要添加日志功能的基类。默认为 Undefined .

未定义的对象是通过调用 undefined .

实施

Undefined 对象通过重写 __underscore__ methods. For example the default Undefined class implements _ _但unicode返回空字符串的方式 `__int__ 而其他人却例外地失败了。通过返回来允许转换为int 0 您可以实现自己的:

class NullUndefined(Undefined):
    def __int__(self):
        return 0
    def __float__(self):
        return 0.0

要禁用某个方法,只需重写它并引发 _undefined_exception . 因为这是未定义对象中非常常见的习惯用法,所以有helper方法 _fail_with_undefined_error() 这会自动产生错误。这是一个像普通的 Undefined 但是迭代时的阻塞:

class NonIterableUndefined(Undefined):
    __iter__ = Undefined._fail_with_undefined_error

语境

class jinja2.runtime.Context

模板上下文保存模板的变量。它存储传递给模板的值以及模板导出的名称。创建实例既不受支持也不有用,因为它是在模板评估的各个阶段自动创建的,不应该手工创建。

上下文是不可变的。修改 parent 不能 发生和修改 vars 仅允许来自生成的模板代码。模板筛选器和标记为的全局函数 contextfunction() s获取作为第一个参数传递的活动上下文,并允许以只读方式访问该上下文。

模板上下文支持只读dict操作 (get, keys, values, items, iterkeys, itervalues, iteritems, _ _getitem__, __contains__ )另外还有一个 resolve() 方法不会失败 KeyError 但是返回 Undefined 缺少变量的对象。

parent

模板查找的只读全局变量的dict。这些要么来自另一个 Context ,从 Environment.globalsTemplate.globals 或者指向通过将全局变量与传递给呈现函数的变量组合而创建的dict。不得更改。

vars

模板局部变量。此列表包含来自 parent 范围以及本地修改和从模板导出的变量。模板将在模板评估期间修改此dict,但不允许筛选器和上下文函数修改它。

environment

加载模板的环境。

exported_vars

此集合包含模板导出的所有名称。名称的值位于 vars dict.为了得到导出变量的dict副本, get_exported() 可以使用。

name

拥有此上下文的模板的加载名称。

blocks

模板中块的当前映射的dict。此dict中的键是块的名称,值是已注册的块列表。每个列表中的最后一项是当前活动块(继承链中最新的)。

eval_ctx

评估背景 .

call(callable, *args, **kwargs)

使用提供的参数和关键字参数调用Callable,但如果Callable是一个 contextfunction()environmentfunction() .

get_all()

以dict的形式返回完整的上下文,包括导出的变量。出于优化原因,这可能不会返回实际副本,因此请小心使用它。

get_exported()

使用导出的变量获取新的dict。

resolve(key)

查找变量 __getitem__get 但是返回 Undefined 已查找名为的对象。

实施

上下文是不可变的,原因与Python的帧局部变量在函数内部是不可变的相同。jinja2和python都没有将上下文/帧局部变量用作变量的数据存储,而是只用作主数据源。

当模板访问模板未定义的变量时,jinja2会在上下文中查找该变量,然后将该变量视为在模板中定义的变量。

加载器

加载程序负责从文件系统等资源加载模板。环境将把编译后的模块保存在内存中,就像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 file(path) as f:
            source = f.read().decode('utf-8')
        return source, path, lambda: mtime == getmtime(path)
get_source(environment, template)

(source, filename, uptodate) 或提高 TemplateNotFound 找不到模板时出错。

返回的元组的源部分必须是作为Unicode字符串或ASCII字节串的模板源。文件名应该是文件系统上的文件名(如果是从那里加载的),否则 None . 如果没有使用加载程序扩展名,则python将使用该文件名进行跟踪。

元组中的最后一项是 uptodate 功能。如果启用了自动重新加载,则始终调用它来检查模板是否更改。没有传递参数,因此函数必须将旧状态存储在某个位置(例如在闭包中)。如果它回来 False 将重新加载模板。

load(environment, name, globals=None)

加载模板。此方法在缓存中查找模板或通过调用 get_source() . 子类不应将此方法重写为处理其他加载器集合的加载器(例如 PrefixLoaderChoiceLoader )不会调用此方法,但 get_source 直接。

这里列出了内置加载器jinja2:

class jinja2.FileSystemLoader(searchpath, encoding='utf-8', followlinks=False)

从文件系统加载模板。此加载程序可以在文件系统的文件夹中找到模板,并且是加载模板的首选方法。

加载程序将模板的路径作为字符串,或者如果需要多个位置,则按照给定的顺序查找这些位置的列表:

>>> loader = FileSystemLoader('/path/to/templates')
>>> loader = FileSystemLoader(['/path/to/templates', '/other/path'])

默认情况下,模板编码为 'utf-8' 可以通过设置 encoding 其他参数。

要遵循符号链接,请设置 跟踪链接 参数到 True ::

>>> loader = FileSystemLoader('/path/to/templates', followlinks=True)

在 2.8+ 版更改: 这个 跟踪链接 已添加参数。

class jinja2.PackageLoader(package_name, package_path='templates', encoding='utf-8')

从python鸡蛋或包中加载模板。它是用python包的名称和该包中模板的路径构造的:

loader = PackageLoader('mypackage', 'views')

'templates' 假设。

默认情况下,模板编码为 'utf-8' 可以通过设置 encoding 其他参数。由于鸡蛋的性质,只有从文件系统而不是zip文件加载包时才能重新加载模板。

class jinja2.DictLoader(mapping)

从python dict加载模板。它将unicode字符串的dict绑定到模板名。此加载程序可用于单元测试:

>>> loader = DictLoader({'index.html': 'source here'})

因为自动重新加载很少有用,所以在默认情况下禁用。

class jinja2.FunctionLoader(load_func)

一种装入程序,它传递一个执行装入的函数。函数接收模板的名称,必须返回一个包含模板源的Unicode字符串和表单中的元组。 (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' 第二个文件。

class jinja2.ChoiceLoader(loaders)

这个加载器的工作原理是 PrefixLoader 只是没有指定前缀。如果一个加载程序找不到模板,则尝试下一个。

>>> loader = ChoiceLoader([
...     FileSystemLoader('/path/to/user/templates'),
...     FileSystemLoader('/path/to/system/templates')
... ])

如果您希望允许用户覆盖来自不同位置的内置模板,这将非常有用。

class jinja2.ModuleLoader(path)

此加载程序从预编译的模板加载模板。

示例用法:

>>> loader = ChoiceLoader([
...     ModuleLoader('/path/to/compiled/templates'),
...     FileSystemLoader('/path/to/templates')
... ])

模板可以预编译为 Environment.compile_templates() .

字节码缓存

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)

基于文件系统的字节码缓存的更高级版本是jinja2的一部分。

clear()

清除缓存。Jinja2不使用此方法,但应实现此方法,以允许应用程序清除特定环境使用的字节码缓存。

dump_bytecode(bucket)

子类必须重写此方法才能将字节码从存储桶写回缓存。如果它不能做到这一点,它就不能默默地失败,而是引发一个异常。

load_bytecode(bucket)

子类必须重写此方法才能将字节码加载到bucket中。如果他们在缓存中找不到bucket的代码,那么它就不能做任何事情。

class jinja2.bccache.Bucket(environment, key, checksum)

存储桶用于存储一个模板的字节码。它由字节码缓存创建和初始化,并传递给加载函数。

Buckets从分配的缓存中获取内部校验和,并使用该校验和自动拒绝过期的缓存材料。单独的字节码缓存子类不必关心缓存的无效性。

environment

这个 Environment 创造了这个桶。

key

此bucket的唯一缓存密钥

code

如果加载了字节码,则返回字节码,否则 None .

bytecode_from_string(string)

从字符串加载字节码。

bytecode_to_string()

将字节码作为字符串返回。

load_bytecode(f)

从文件或类似文件的对象加载字节码。

reset()

重置存储桶(卸载字节码)。

write_bytecode(f)

将字节码转储到传递的文件或类似文件的对象中。

内置字节码缓存:

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.core.cache.cache._client

传递给构造函数的客户端的最小接口是:

class MinimalClientInterface
set(key, value[, timeout])

value 是一个字符串 timeout 键的超时。如果未提供超时,则应假定为默认超时或不超时;如果提供超时,则应假定为一个整数,其中包含缓存项应存在的秒数。

get(key)

返回缓存键的值。如果缓存中不存在该项,则返回值必须为 None .

构造函数的其他参数是在实际缓存键之前添加的所有键的前缀,以及缓存系统中字节码的超时。我们建议高(或无)超时。

此字节码缓存不支持清除缓存中的已用项。clear方法是一个无操作函数。

2.7 新版功能: 增加了对忽略memcache错误的支持 ignore_memcache_errors 参数。

异步支持

从2.9版开始,jinja2还支持python asyncawait 构造。就模板设计者而言,这个特性对他们来说是完全不透明的,但是作为一个开发人员,你应该知道它是如何实现的,因为它会影响你可以安全地暴露在模板环境中的API类型。

首先,您需要知道,默认情况下,异步支持被禁用,因为启用它将在后台生成不同的模板代码,这些代码将通过Asyncio事件循环传递所有内容。理解这一点很重要,因为它对您所做的工作有一定影响:

  • 模板呈现将要求为当前线程设置事件循环 (asyncio.get_event_loop 需要退回一个)

  • 所有模板生成代码都在内部运行异步生成器,这意味着即使使用了非同步方法,也要付出性能代价!

  • 如果启用了异步模式,则同步方法基于异步方法,这意味着 render 例如,将在内部调用 render_async 并作为当前事件循环的一部分运行它,直到执行完成。

await 您通常会在python中发出暗示。但是,这只适用于函数调用。例如,如果一个属性是一个可等待的对象,那么这不会导致预期的行为。

同样的迭代 for 循环支持异步迭代器。

政策

从Jinja 2.9开始,可以在环境中配置策略,这对过滤器和其他模板构造的行为有轻微影响。它们可以配置为 policies 属性。

例子::

env.policies['urlize.rel'] = 'nofollow noopener'
compiler.ascii_str

如果jinja2只存储ASCII文本而不是unicode字符串,则python 2上的此布尔控件。这一点以前一直适用于2.9以下的Jinja版本,现在可以更改。传统上是这样做的,因为python 2中的一些API对于unicode字符串(例如datetime strftime API)失败得很严重。然而,现在有时情况是相反的(例如str.format)。如果设置为false,则所有字符串都将在内部存储为Unicode。

truncate.leeway

为配置leeway默认值 truncate 过滤器。2.9中介绍的leeway,但为了恢复与旧模板的兼容性,可以将其配置为 0 把以前的行为恢复过来。默认值为 5 .

urlize.rel

一个字符串,用于定义 rel 生成的链接的属性 urlize 过滤器。始终添加这些项目。默认值为 noopener .

urlize.target

为来自的链接发出的默认目标 urlize 如果调用未显式定义其他目标,则筛选。

json.dumps_function

如果将此值设置为 None 然后 tojson 过滤器将使用此函数而不是默认函数进行转储。注意,这个函数应该接受将来可能从过滤器传递的任意额外参数。当前唯一可以传递的参数是 indent . 默认转储函数为 json.dumps .

json.dumps_kwargs

要传递给dump函数的关键字参数。默认值为 {{'sort_keys': True}} .

ext.i18n.trimmed

如果设置为 True{{% trans %}} 街区 i18n扩展 将始终统一换行符和周围空白,就像 trimmed 使用了修饰符。

公用事业

如果将自定义过滤器或函数添加到jinja2环境中,这些助手函数和类将非常有用。

jinja2.environmentfilter(f)

标记与环境相关的筛选器的修饰符。电流 Environment 作为第一个参数传递给筛选器。

jinja2.contextfilter(f)

标记上下文相关筛选器的修饰符。电流 Context 将作为第一个参数传递。

jinja2.evalcontextfilter(f)

用于标记eval上下文相关筛选器的修饰符。eval上下文对象作为第一个参数传递。有关eval上下文的详细信息,请参见 评估背景 .

2.4 新版功能.

jinja2.environmentfunction(f)

此修饰符可用于将函数或方法标记为环境可调用。这个装饰工的工作原理和 contextfunction() Environment 而不是上下文。

jinja2.contextfunction(f)

此修饰符可用于标记可调用的函数或方法上下文。将上下文可调用的 Context 从模板调用时作为第一个参数。如果函数希望访问上下文或上下文对象上提供的函数,则此选项非常有用。例如,返回当前模板导出的模板变量排序列表的函数如下所示:

@contextfunction
def get_exported_names(context):
    return sorted(context.exported_vars)
jinja2.evalcontextfunction(f)

此修饰符可用于将函数或方法标记为可调用的eval上下文。这和 contextfunction() 但不传递上下文,而是传递一个计算上下文对象。有关eval上下文的详细信息,请参见 评估背景 .

2.4 新版功能.

jinja2.escape(s)

转换字符 &<>'"s 到HTML安全序列。如果需要在HTML中显示可能包含此类字符的文本,请使用此选项。此函数不会转义具有HTML表示形式(如已转义数据)的对象。

返回值为 Markup 字符串。

jinja2.clear_caches()

Jinja2为环境和Lexer保留内部缓存。这些都是为了让Jinja2不必一直重建环境和雷克萨斯。通常情况下,您不必担心这一点,但是如果您要测量内存消耗量,您可能需要清理缓存。

jinja2.is_undefined(obj)

Undefined 但看起来好多了。这可用于想要对未定义变量做出反应的自定义筛选器或测试。例如,自定义默认筛选器可以如下所示:

def default(var, default=''):
    if is_undefined(var):
        return default
    return var
class jinja2.Markup([string])

可以安全地插入HTML或XML文档的字符串,可能是因为它被转义了,也可能是因为它被标记为安全。

将对象传递给构造函数将其转换为文本并对其进行包装,以在不进行转义的情况下将其标记为安全的。要转义文本,请使用 escape() 而是类方法。

>>> Markup('Hello, <em>World</em>!')
Markup('Hello, <em>World</em>!')
>>> Markup(42)
Markup('42')
>>> Markup.escape('Hello, <em>World</em>!')
Markup('Hello &lt;em&gt;World&lt;/em&gt;!')

这实现了 __html__() 一些框架使用的接口。传递实现的对象 __html__() 将包装该方法的输出,标记为安全。

>>> class Foo:
...     def __html__(self):
...         return '<a href="/foo">foo</a>'
...
>>> Markup(Foo())
Markup('<a href="/foo">foo</a>')

这是文本类型的子类 (str 在Python 3中, unicode 在Python 2中)。它具有与该类型相同的方法,但所有方法都会转义其参数并返回 Markup 实例。

>>> Markup('<em>%s</em>') % 'foo & bar'
Markup('<em>foo &amp; bar</em>')
>>> Markup('<em>Hello</em> ') + '<foo>'
Markup('<em>Hello</em> &lt;foo&gt;')
classmethod escape(s)

转义字符串。电话 escape() 并确保对于子类返回正确的类型。

striptags()

unescape() 标记、删除标记并将空白规范化为单个空格。

>>> Markup('Main &raquo;        <em>About</em>').striptags()
'Main » About'
unescape()

将转义标记转换回文本字符串。这将用HTML实体所代表的字符替换HTML实体。

>>> Markup('Main &raquo; <em>About</em>').unescape()
'Main » <em>About</em>'

注意

Jinja2 Markup 类至少与挂架和Genshi兼容。预计更多的模板引擎和框架将 __html__ 概念很快。

例外情况

exception jinja2.TemplateError(message=None)

所有模板错误的基类。

exception jinja2.UndefinedError(message=None)

在模板尝试操作时引发 Undefined .

exception jinja2.TemplateNotFound(name, message=None)

如果模板不存在则引发。

exception jinja2.TemplatesNotFound(names=(), message=None)

喜欢 TemplateNotFound TemplateNotFound 异常,因此只捕获基本异常将同时捕获这两个异常。

2.2 新版功能.

exception jinja2.TemplateSyntaxError(message, lineno, name=None, filename=None)

引发以告诉用户模板有问题。

message

错误消息为utf-8 bytestring。

lineno

发生错误的行号

name

模板的加载名称为Unicode字符串。

filename

将模板作为文件系统编码中的字节串加载的文件名(很可能是Windows系统上的utf-8或mbcs)。

文件名和错误消息是字节字符串而不是Unicode字符串的原因是python 2.x没有使用Unicode来处理异常、跟踪以及编译器。这将随python 3而改变。

exception jinja2.TemplateRuntimeError(message=None)

模板引擎中的一般运行时错误。在某些情况下,Jinja可能会提出这个例外。

exception jinja2.TemplateAssertionError(message, lineno, name=None, filename=None)

类似于模板语法错误,但涵盖了在编译时模板中的某些内容导致了不一定是由语法错误引起的错误的情况。但是它是 TemplateSyntaxError 具有相同的属性。

自定义过滤器

自定义过滤器只是常规的python函数,它将过滤器的左侧作为第一个参数,并将传递给过滤器的参数作为额外的参数或关键字参数。

例如在过滤器中 {{{{ 42|myfilter(23) }}}} 函数将用 myfilter(42, 23) . 例如,这里有一个简单的过滤器,可以应用于日期时间对象来格式化它们:

def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
    return value.strftime(format)

您可以通过更新 filters 环境问题:

environment.filters['datetimeformat'] = datetimeformat

在模板内,可以按如下方式使用:

written on: {{ article.pub_date|datetimeformat }}
publication date: {{ article.pub_date|datetimeformat('%d-%m-%Y') }}

还可以将筛选器传递给当前模板上下文或环境。如果过滤器想要返回未定义的值或检查当前 autoescape 设置。为此,存在三个装饰师: environmentfilter()contextfilter()evalcontextfilter() .

这里有一个小示例过滤器,它将文本拆分为HTML换行符和段落,并在启用自动转义时将返回值标记为安全的HTML字符串:

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')

@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br>\n'))
                          for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

上下文筛选器的工作方式与第一个参数是当前活动的相同 Context 而不是环境。

评估背景

评估上下文(简称eval context或eval ctx)是jinja 2.4中引入的一个新对象,可以在运行时激活和停用已编译的功能。

目前它只用于启用和禁用自动转义,但也可以用于扩展。

在以前的Jinja版本中,为了检查环境中的自动转义状态,过滤器和函数被标记为环境可调用文件。在新版本中,我们鼓励您从评估上下文中检查设置。

以前的版本:

@environmentfilter
def filter(env, value):
    result = do_something(value)
    if env.autoescape:
        result = Markup(result)
    return result

在新版本中,您可以使用 contextfilter() 并从实际上下文访问评估上下文,或者使用 evalcontextfilter() 它直接将评估上下文传递给函数:

@contextfilter
def filter(context, value):
    result = do_something(value)
    if context.eval_ctx.autoescape:
        result = Markup(result)
    return result

@evalcontextfilter
def filter(eval_ctx, value):
    result = do_something(value)
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

运行时不能修改计算上下文。修改只能在 nodes.EvalContextModifiernodes.ScopedEvalContextModifier 来自扩展,而不是Eval上下文对象本身。

class jinja2.nodes.EvalContext(environment, template_name=None)

保存评估时间信息。自定义属性可以在扩展中附加到它。

autoescape

TrueFalse 取决于自动转义是否处于活动状态。

volatile

True 如果编译器在编译时无法计算某些表达式。在运行时,这应该始终是 False .

自定义测试

测试就像过滤器一样工作,只是测试无法访问环境或上下文,并且无法链接它们。测试的返回值应为 TrueFalse . 测试的目的是为模板设计者提供执行类型和一致性检查的可能性。

这里是一个简单的测试,检查变量是否是质数:

import math

def is_prime(n):
    if n == 2:
        return True
    for i in xrange(2, int(math.ceil(math.sqrt(n))) + 1):
        if n % i == 0:
            return False
    return True

您可以通过更新 tests 环境问题:

environment.tests['prime'] = is_prime

然后,模板设计器可以使用如下测试:

{% if 42 is prime %}
    42 is a prime number
{% else %}
    42 is not a prime number
{% endif %}

超空间

变量存储在 Environment.globals dict是特殊的,因为它们也可用于导入的模板,即使它们是在没有上下文的情况下导入的。这是一个可以放置变量和函数的地方,这些变量和函数应该随时可用。另外 Template.globals 存在的变量可用于所有可用的特定模板 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 Jinja2 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() 同一模板或兼容模板。此呈现函数由编译器根据模板代码生成,并返回生成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 新版功能.

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) == set(['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]

此函数对于依赖项跟踪很有用。例如,如果要在布局模板更改后重建网站的部分内容。