API

本文档描述 Jinja 的API,而不是模板语言。 它对于实现应用程序模板接口的人员是最有用的参考,而不是创建 Jinja 模板的人员。

基础

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

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

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

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

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

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

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

要使用某些变量渲染它,只需调用render()方法:

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

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

关于自动转义的说明

在 Jinja 的未来版本中,出于安全原因,我们可能会默认启用自动转义。 因此,建议你立即显式配置自动转义,而不是依赖默认值。

Unicode|

Jinja2 内部使用 Unicode ,这意味着你必须向渲染函数传递 Unicode 对象或只包含 ASCII 字符的 bytestring。 此外,默认情况下将换行符标准化为 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 向后兼容。 对于 Jinja,模板的默认编码假定为 utf-8。

无法使用 Jinja 处理非 Unicode 数据。 原因是 Jinja 已在语言级别上使用 Unicode。 例如,Jinja 将不间断空格视为表达式内的有效空白,这需要了解 Unicode 字符串上的编码或操作。

有关 Python 中的 Unicode 的更多详细信息,请查看优秀的Unicode 文档

另一件重要的事情是 Jinja 如何处理模板中的字符串文本。 原生实现会对所有字符串字面值使用 Unicode ,但过去证明这是有问题的,因为一些库显式地检查类型是否为 str 例如,datetime.strftime 不接受 Unicode 参数。 为了不彻底破坏它, Jinja 对只有 ASCII 的字符串返回 str,而对其它所有字符串返回 unicode

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

高层 API

高级 API 是在应用程序中用于加载和呈现 Jinja 模板的 API。 相反,低层 API只在你想深入挖掘 Jinja 或开发扩展时才有用。

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,则删除块后的第一个换行(块,而不是变量标记!)。 默认值为False

lstrip_blocks

如果设置为True,则则从行的开头到块的前导空格和Tab都将修剪掉。 默认值为False

newline_sequence

开始一个新行的序列。 必须为'\n''\r\n'之一。 '\r' 默认值为'\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 中更改: 自动转义现在可以成为一个函数

loader

此环境的模板加载程序。

cache_size

缓存的大小。 默认值为400这意味着如果加载了 400 多个模板,加载程序将清除最近使用最少的模板。 如果缓存大小设置为0个模板,则一直重新编译,如果缓存大小为-1则不会清除缓存。

更改日志

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

auto_reload

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

bytecode_cache

如果设置为字节码缓存对象,此对象将为内部 Jinja 字节码提供缓存,以便在模板未更改时不必对其进行分析。

有关详细信息,请参阅Bytecode Cache

enable_async

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

shared

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

sandboxed

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

filters

此环境的筛选器的一个字典。 只要未加载任何模板,可以安全地添加新过滤器或删除旧过滤器。 有关自定义过滤器,请参阅Custom Filters 对于有效的筛选器名称,请查看Notes on Identifiers

tests

此环境的测试函数的一个字典。 只要没有加载模板,就可以安全地修改此字典。 有关自定义测试,请参阅Custom Tests 对于有效的测试名称,请查看Notes on Identifiers

globals

全局变量的一个字典。 这些变量始终在模板中可用。 只要没有加载模板,就可以安全地修改此字典。 有关详细信息The Global Namespace 对于有效的对象名称,请查看Notes on Identifiers

policies

带有Policies的字典。 可以重新配置这些功能以更改运行时行为或某些模板功能。 通常这些与安全有关。

code_generator_class

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

context_class|

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

overlay([options])

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

在完全设置初始环境后,应创建叠加。 并非所有属性都是真正链接的,有些属性只是复制过来,因此原始环境的修改可能不会发光。

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

name 创建一个新的 Undefined 对象。 这对于可能为某些操作返回未定义对象的筛选器或函数很有用。 提示外的所有参数都应作为关键字参数提供,以便更好地可读性。 如果提供,提示将用作异常的错误消息,否则将自动从objname生成错误消息。 如果生成未定义对象时未定义对象完成未定义对象不允许执行某些工作,则引发以 exc身份提供的异常。 默认的异常是UndefinedError 如果提供了提示,则名称可能会省略。

创建未定义对象的最常见方法是仅提供名称:

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

如果名称obj已知(例如,因为访问了属性),则应将其传递给未定义的对象,即使提供了自定义提示也是如此。 这为未定义的对象提供了增强错误消息的可能性。

add_extension(extension)

创建环境后添加扩展。

更改日志

版本 2.5 中的新增功能。

compile_expression(source, undefined_to_none=True)

一种方便的 helper 方法,它返回一个可调用方法,该调用接受在表达式中显示为变量的关键字参数。 如果调用它,则返回表达式的结果。

如果应用程序希望在模板"配置文件"或类似情况下使用与 Jinja 相同的规则,则此功能非常有用。

示例用法:

>>> env = Environment()
>>> expr = env.compile_expression('foo == 42')
>>> expr(foo=23)
False
>>> expr(foo=42)
True

如果表达式返回未定义的值,则返回值将转换为None。 这可以通过将undefined_to_none设置为False来更改。

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

版本 2.1 中的新增功能。

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

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

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

默认情况下,将忽略模板编译错误。 如果提供 log_function,则错误日志将记录下来。 如果希望模板语法遇到错误则中止编译,可以将 ignore_errors 设置为 False,这时语法错误将抛出异常。

如果 py_compile 设置为True, .pyc 文件而不是标准 的 .py 文件将写入 target 中。 该标志在 pypy 和 Python 3 上不做任何事情,在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()否则将get_template()

更改日志

版本 2.3 中的新增功能。

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

从加载器加载模板。 如果配置了加载程序,此方法会向加载程序请求模板并返回Template 如果参数不是None,则调用join_path()在加载之前获取实际模板名称。

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

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

更改日志

在版本 2.4 中更改: 如果nameTemplate对象,则从函数返回该对象不变。

join_path(template, parent)

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

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

list_templates(extensions=None, filter_func=None)

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

如果模板文件夹中除了实际模板之外还有其他文件,则可以筛选返回的列表。 有两种方法:任一扩展名都设置为模板的文件扩展名列表,或者可以提供filter_func该扩展名是传递模板名称的可调用名称,如果最终应出现在结果列表中,则应返回True。

如果加载程序不支持,则引发TypeError

更改日志

版本 2.4 中的新增功能。

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

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

在版本 2.11 中更改: 如果名称Undefined,则引发UndefinedError 如果未找到模板,并且名称包含Undefined,则消息更有用。

更改日志

在版本 2.4 中更改: 如果名称包含Template对象,则从未更改的函数返回该对象。

版本 2.3 中的新增功能。

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

模板的全局变量的字典。 修改这个字典是不安全的,因为它可能与其它模板或加载该模板的环境共享。

name

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

filename

如果模板是从那里加载的,则文件系统上的文件名。 否则,这是

render([context])

此方法接受与听写构造函数相同的参数:听写、听写子类或某些关键字参数。 如果未提供参数,则上下文将为空。 这两个调用执行相同的操作:

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

这将返回呈现的模板作为单码字符串。

generate([context])

对于非常大的模板,不一次呈现整个模板,而是逐个计算每个语句,并逐块生成单据,这非常有用。 此方法基本上完全这样做,并返回一个生成器,该生成器将一个又一个项作为单码字符串生成。

它接受与render()相同的参数。

stream([context])

工作原理与generate()完全相同,但返回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属性类似,但它将在每次调用时计算模板,而不是缓存它。 也可以提供一个听写,然后用作上下文。 参数与new_context()方法相同。

property module

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

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

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

class jinja2.environment.TemplateStream

模板流的工作方式与普通 python 生成器非常类似,但它可以缓冲多个项以减少总迭代次数。 根据默认值,输出是未缓冲的,这意味着对于模板中的每个未缓冲指令,将生成一个单码字符串。

如果启用了缓冲区大小为 5 的缓冲,则五个项目将合并到一个新的 Unicode 字符串中。 如果要通过 WSGI 将大型模板流式传输到客户端,WSGI 在每次迭代后刷新,这主要很有用。

disable_buffering()

禁用输出缓冲。

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

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

示例用法:

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

启用缓冲。 在生成项之前缓冲大小项。

自动转义

更改日志

在版本 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的默认值。 如果不匹配,则自动转义的初始值设置为默认值

出于安全原因,此函数操作不区分大小写。

更改日志

版本 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 Overrides)。

关于标识符的说明|

Jinja 使用 Python 命名规则。 有效标识符可以是 Python 接受的 Unicode 字符的任意组合。

Filter 和 test 在单独的命名空间中进行查看,标识符语法稍有修改。 Filter 和 test 可能包含按主题对 filter 和 test 进行分组的点。 例如,将函数添加到 filter 的字典并称之为 to.unicode 是完全有效的。 Filter 和 test 标识符的正则表达式是 [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*`

Undefined 类型

这些类可用作未定义的类型。 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
_undefined_hint|

或带有未定义对象的错误消息的单码字符串。

_undefined_obj|

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

_undefined_name|

未定义的变量 / 属性的名称,或者如果不存在此类信息,则为"无"。

_undefined_exception

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

_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 中新增。

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

在打印和迭代以及布尔测试和各种比较时树皮的未定义。 换句话说:除了检查是否使用定义的测试定义它之外,您对此无能为力。

>>> 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 — 要使用的 logger。 如果未提供,将创建一个默认的 logger。

  • base — 要添加日志记录功能的基类。 这默认为Undefined

未定义的对象是通过调用undefined创建对象的。

实现

Undefined的对象是通过重写特殊__underscore__方法实现的。 例如,默认Undefined类实现__unicode__它返回空字符串的方式,但是__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):
    __iter__ = Undefined._fail_with_undefined_error

上下文

class jinja2.runtime.Context

模板上下文包含模板的变量。 它存储传递给模板的值以及模板导出的名称。 不支持创建它的实例而且也没有用处,因为它在模板求值的各个阶段自动创建,不应手动创建。

上下文是不可变的。 不得parent变量进行修改,并且只允许从生成的模板代码对vars进行修改。 模板筛选器和标记为contextfunction()的全局函数将活动上下文作为第一个参数传递,并允许只读访问上下文。

模板上下文支持字典的只读操作(get, keys, values, items, iterkeys, itervalues, iteritems, __getitem__, __contains__)。 此外,还有一个resolve()方法,该方法不会因KeyError而失败,但会为缺少的变量返回Undefined的对象。

parent

模板查找的只读全局变量的口述。 这些可以来自另一个Context,来自Environment.globalsTemplate.globals或者指向通过将全局变量与传递给呈现函数的变量组合创建的听写。 绝不能改变它。

vars|

模板局部变量。 此列表包含来自parent作用域的环境和上下文函数以及模板中的本地修改和导出变量。 模板将在模板评估期间修改此听写,但不允许筛选器和上下文函数修改它。

environment

加载模板的环境。

exported_vars|

此集包含模板导出的所有名称。 名称的值在vars dict 中。 为了获取导出变量的副本作为听写,可以使用get_exported()

name

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

blocks

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

eval_ctx|

当前Evaluation Context

call(callable, *args, **kwargs)

使用提供的参数和关键字参数调用可调用,但如果可调用是contextfunction()environmentfunction(),则将活动上下文或环境作为第一个参数注入。

get_all()

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

get_exported()

获取包含导出变量的新听写。

resolve(key)

查找像__getitem__get这样的变量,但返回一个Undefined的对象,并查找名称的名称。

实现

上下文是不可变的,原因与 Python 的帧局部变量在函数内部是不可变的原因相同。 Jinja 和 Python 都不使用上下文/帧局部变量作为变量的数据存储,而仅用作主数据源。

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

Loaders

加载程序负责从资源(如文件系统)加载模板。 环境会将编译的模块保留在内存中,如Python的sys.模块 sys.模块不同,默认情况下,此缓存的大小有限,模板会自动重新加载。 所有加载器都是BaseLoader的子类。 如果要创建自己的加载程序,子类BaseLoader和重写get_source。

class jinja2.BaseLoader

所有 loader 的基类。 子类此和重写get_source实现自定义加载机制。 环境提供了一个get_template方法,该方法调用加载器的加载方法来获取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 错误。

返回元组的 source 必须是模板源的 unicode 字符串或 ASCII 字节字符串。 如果文件是从文件系统加载的,filename 应为文件系统上文件的名称,否则为 None 如果没有使用加载程序扩展,则 Python 会将文件名用于回溯。

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

load(environment, name, globals=None)

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

这里列出 Jinja 提供的内置加载程序:

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

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

加载程序将模板的路径作为字符串,或者如果多个位置需要一个列表,然后按给定顺序进行查看:

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

根据默认值,模板编码为'utf-8'可以通过将编码参数设置为其他参数来更改。

要跟踪符号链接,请将 followlinks 参数设置为True

>>> loader = FileSystemLoader('/path/to/templates', followlinks=True)
更改日志

在版本 2.8 中更改: 添加了followlinks参数。

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

从 Python 包中的目录加载模板。

参数
  • package_name = 导入包含模板目录的包的名称。

  • package_path = 包含模板的导入包中的目录。

  • encoding — 模板文件的编码。

下面的示例在project.ui包中的pages目录中查找模板。

loader = PackageLoader("project.ui", "pages")

仅支持作为目录(标准点行为)或 zip/egg 文件(不太常见)安装的包。 用于在包中内检数据的 Python API 太有限,无法支持此加载程序所需的其他安装方法。

PEP 420命名空间包的支持有限。 假定模板目录仅位于一个命名空间参与者中。 不支持参与命名空间的 Zip 文件。

在版本 2.11.0 中更改: 不再使用setuptools作为依赖项。

在版本 2.11.0 中更改: 有限的 PEP 420 命名空间包支持。

class jinja2.DictLoader(mapping)

从 Python 字典加载模板。 它传递了绑定到模板名称的单码字符串的口述。 此加载程序可用于单元测试:

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

因为自动重新加载很少有用,因此默认禁用此功能。

class jinja2.FunctionLoader(load_func)

传递执行加载的函数的加载器。 函数接收模板的名称,并且必须返回带有模板源的单码字符串、表单中的元组(源、文件名、更新节)"无"(如果模板不存在)。

>>> def load_template(name):
...     if name == 'index.html':
...         return '...'
...
>>> loader = FunctionLoader(load_template)

在启用自动重加载时,将调用up 函数,如果模板仍然是最新的,则必须返回True。 有关详细信息,请查看具有相同返回值的BaseLoader.get_source()

class jinja2.PrefixLoader(mapping, delimiter='/')

传递加载器的加载器,其中每个加载器绑定到前缀。 前缀从模板中按每个默认值的斜杠分隔,可以通过将分隔符参数设置为其他参数来更改:

loader = PrefixLoader({
    'app1':     PackageLoader('mypackage.app1'),
    'app2':     PackageLoader('mypackage.app2')
})

通过加载'app1/index.html'从 app1 包加载文件,从第二个包加载'app2/index.html'文件。

class jinja2.ChoiceLoader(loaders)

此加载程序的工作方式与前缀加载器一样,只是未指定前缀。 如果一个加载程序找不到模板,则尝试下一个加载程序。

>>> 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()进行预编译。

字节码缓存

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)

子类必须重写此方法,才能将字节码从存储桶写回缓存。 如果它不能这样做,它不得以静默方式失败,而是引发异常。

load_bytecode(bucket)

子类必须重写此方法才能将字节码加载到存储桶中。 如果他们无法在存储桶的缓存中找到代码,则不得执行任何操作。

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

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

存储桶从分配的缓存中获取内部校验和,并使用此自动拒绝过时的缓存材料。 单个字节码缓存子类不必关心缓存失效。

环境 |

创建存储桶Environment

key

此存储桶的唯一缓存键

code

字节码(如果已加载,否则为"无"。

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

此字节码缓存支持使用清除方法清除缓存。

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

将字节码存储在缓存中。 字符串,超时键的超时。 如果未提供默认超时或不应假定超时,则如果提供超时是缓存项应存在的秒数的整数。

get(key)

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

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

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

更改日志

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

异步支持

更改日志

版本 2.9 中的新增功能。

Jinja 支持 Python 的 asyncawait 语法。 对于模板设计器,此支持(启用时)是完全透明的,模板的外观仍然完全相同。 但是,开发人员应了解实现,因为它会影响可以使用的 API 类型。

默认情况下,异步支持被禁用。 启用它将导致环境在后台编译不同的代码,以便在异步事件循环中处理异步和同步代码。 这具有以下含义:

  • 模板呈现需要事件循环对当前线程可用。 asyncio.get_event_loop()必须返回事件循环。

  • 编译的代码使用await等待函数和属性,并使用异步循环 为了支持在此上下文中同时使用异步和同步函数,在所有调用和访问周围放置了一个小包装器,与纯异步代码相比,这会增加开销。

  • 同步方法和筛选器会根据需要围绕其相应的异步实现成为包装器。 例如,render调用async_render|map支持异步迭代。

可等待对象可以从模板中的函数返回,模板中的任何函数调用都将自动等待结果。 通常awaitPython 中添加 await 是隐含的。 例如,可以提供从数据库中异步加载数据的方法,从模板设计器的角度来看,它可以像调用任何其他函数一样调用。

Policies

从 Jinja 2.9 开始,可以在环境上配置 policies,从而影响 filters 和其它模板构造的行为。 可以使用policies属性配置它们。

示例:

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

这个布尔值在 Python 2 上控制 Jinja 是否应该将纯 ASCII 字面值存储为字节字符串而不是 unicode 字符串。 2.9 以前的 Jinja 版本始终开启,现在则可以更改。 之前这样做是因为 Python 2 中的某些 API 在 unicode 字符串上严重错误 (例如 datetime 的 strftime API)。 然而,现在事实有时反过来了(例如str.format)。 如果设置为 False,则所有字符串在内部存储为 unicode。

truncate.leeway

配置truncate filter 的回旋余地默认值。 如 2.9 中介绍的那样,为了恢复与旧模板的兼容性,可以将它配置为0来恢复旧行为。 默认值为5

urlize.rel

一个字符串,定义 urlize filter 生成的链接的 rel 属性内容。 这些内容将始终添加进去。 默认值为 noopener

urlize.target

如果调用未显式定义其它目标,则为 urlize filter 的链接生成的默认目标。

json.dumps_function

如果此值设置为 None 以外的值,则tojson filter 将使用此函数而不是默认函数转储。 请注意,此函数应接受将来可能从筛选器传递的任意额外参数。 目前唯一可能传递的参数是 indent 默认转储函数是json.dumps

json.dumps_kwargs

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

ext.i18n.trimmed

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

实用工具

如果将自定义筛选器或函数添加到 Jinja 环境,这些帮助器函数和类非常有用。

jinja2.environmentfilter(f)

用于标记环境相关筛选器的修饰器。 当前Environment作为第一个参数传递给筛选器。

jinja2.contextfilter(f)

用于标记上下文相关筛选器的修饰器。 当前Context将作为第一个参数传递。

jinja2.evalcontextfilter(f)

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

更改日志

版本 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()类似,但传递的是计算上下文对象,而不是传递上下文。 有关评估上下文的详细信息,请参阅Evaluation Context

更改日志

版本 2.4 中的新增功能。

jinja2.escape(s)

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

返回值是Markup字符串。

jinja2.clear_caches()

Jinja 为环境和用户保留内部缓存。 这些被使用,使金雅不必重新创建环境和字典所有的时间。 通常,您不必关心这一点,但如果您正在测量内存消耗,则可能需要清理缓存。

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

这是文本类型的子类(在 Python 3 中str 2 中的unicode)。 它具有与该类型相同的方法,但所有方法都转义其参数并返回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 实体。

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

注意

JinjaMarkup类至少与 Pylons 和 Genshi 兼容。 预计更多的模板引擎和框架将很快启动__html__概念。

异常

exception jinja2.TemplateError(message=None)

所有模板错误的基类。

exception jinja2.UndefinedError(message=None)

如果模板尝试对Undefined操作,则引发。

exception jinja2.TemplateNotFound(name, message=None)

如果模板不存在,则引发。

在版本 2.11 中更改: 如果给定名称Undefined,并且未提供任何消息,则引发UndefinedError

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

TemplateNotFound类似,但如果选择了多个模板,则引发模板。 这是TemplateNotFound异常的子类,因此仅捕获基本异常将捕获这两个异常。

在版本 2.11 中更改: 如果名称列表中的名称Undefined,则显示有关该名称未定义的消息,而不是空字符串。

更改日志

版本 2.2 中的新增功能。

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

提出来告诉用户模板有问题。

message

错误消息为 utf-8 通过测试。

lineno

发生错误的行号

name

模板的加载名称作为单码字符串。

filename

在文件系统编码(最有可能是 Utf-8 或 Mmcs)的编码中测试将模板加载的文件名。

文件名和错误消息是字节测试而不是单码字符串的原因是 Python 2.x 没有将 unicode 用于异常和回溯以及编译器。 这将随着 Python 3 的变化而改变。

exception jinja2.TemplateRuntimeError(message=None)

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

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

与模板语法错误类似,但涵盖模板中某些内容在编译时导致错误的情况,该错误不一定是语法错误造成的。 但是,它是TemplateSyntaxError直接子类,具有相同的属性。

自定义过滤器|

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

例如,在筛选器[ 42]myfilter(23) 中,函数将用myfilter(42, 23)调用。 例如,一个简单的筛选器,可应用于 Datetime 对象以设置它们的格式:

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 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 range(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 dic 中的变量是特殊的,因为它们也可用于导入的模板,即使它们导入时没有上下文。 在这里,您可以放置应始终可用的变量和函数。 此外,Template.globals是可用于特定模板的变量,可用于所有render()调用。

底层 API

低级 API 公开的功能可用于了解某些实现详细信息、调试目的或高级extension技术。 除非你确切知道你在做什么,我们不建议使用任何这些。

Environment.lex(source, name=None, filename=None)

对给定的源代码进行代码输入,并返回一个生成器,该生成器将令牌生成为表单中的元数(线、token_type、值)。 这对于extension development调试模板非常有用。

这不执行预处理。 如果要应用扩展的预处理,必须通过preprocess()方法筛选源。

Environment.parse(source, name=None, filename=None)

分析源代码并返回抽象语法树。 编译器使用此节点树将模板转换为可执行的源代码或字节码。 这对于调试或从模板中提取信息非常有用。

如果您正在开发developing Jinja extensions,这为您提供了生成的节点树的良好概述。

Environment.preprocess(source, name=None, filename=None)

使用所有扩展预处理源。 这会自动调用所有解析和编译方法,但不是 lex()因为通常只需要实际的源标记。

Template.new_context(vars=None, shared=False, locals=None)

为此模板创建新Context 提供的 var 将传递到模板。 每个默认值的全局将添加到上下文中。 如果共享设置为True,则数据将像对上下文一样传递到上下文,而不添加全局。

局部变量可以是内部使用的局部变量的口述。

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 在更高版本中引入了一个新的 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) == set(['bar'])
True

实现

在内部,代码生成器用于查找未声明的变量。 这是很好的知道,因为代码生成器可能会在编译期间引发TemplateAssertionError,事实上,此函数当前也可以引发该异常。

jinja2.meta.find_referenced_templates(ast)

从 AST 查找所有引用的模板。 这将在所有硬编码模板扩展、包含和导入上返回一个迭代器。 如果使用动态继承或包含,则将产生"无"。

>>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
>>> list(meta.find_referenced_templates(ast))
['layout.html', None]

此函数可用于依赖项跟踪。 例如,如果要在布局模板更改后重建网站的某些部分。