扩展¶
Jinja 支持可添加额外过滤器、测试、全局变量甚至扩展解析器的扩展。扩展的主要动机是将经常使用的代码移入可重用类中,例如添加对国际化的支持。
添加扩展¶
扩展在创建时添加到 Jinja 环境中。要添加扩展,请将扩展类列表或导入路径传递给 Environment 构造函数的 extensions 参数。以下示例创建一个已加载 i18n 扩展的 Jinja 环境
jinja_env = Environment(extensions=['jinja2.ext.i18n'])
要在创建后添加扩展,请使用 add_extension() 方法
jinja_env.add_extension('jinja2.ext.debug')
i18n 扩展¶
导入名称: jinja2.ext.i18n
i18n 扩展可与 gettext 或 Babel 结合使用。启用后,Jinja 会提供一个 trans 语句,将块标记为可翻译并调用 gettext。
启用后,应用程序必须为 gettext、ngettext,以及可选的 pgettext 和 npgettext 提供函数,无论是在全局还是在渲染时。已添加一个 _() 函数作为 gettext 函数的别名。
环境方法¶
启用扩展后,环境提供以下附加方法
- jinja2.Environment.install_gettext_translations(translations, newstyle=False)¶
- 为环境全局安装翻译。 - translations对象必须实现- gettext、- ngettext,以及可选的- pgettext和- npgettext。支持- gettext.NullTranslations、- gettext.GNUTranslations和 Babel 的- Translations。- 变更日志- 在版本 3.0 中更改: 添加了 - pgettext和- npgettext。- 在版本 2.5 中更改: 添加了新式 gettext 支持。 
- jinja2.Environment.install_null_translations(newstyle=False)¶
- 安装无操作 gettext 函数。如果你想为应用程序准备国际化,但又不想立即实现完整系统,这会很有用。 - 变更日志- 在版本 2.5 中更改: 添加了新式 gettext 支持。 
- jinja2.Environment.install_gettext_callables(gettext, ngettext, newstyle=False, pgettext=None, npgettext=None)¶
- 将给定的 - gettext、- ngettext、- pgettext和- npgettext可调用项安装到环境中。它们的行为应与- gettext.gettext()、- gettext.ngettext()、- gettext.pgettext()和- gettext.npgettext()完全相同。- 如果激活 - newstyle,可调用项将被包装为像新式可调用项一样工作。有关更多信息,请参阅 新式 Gettext。- 变更日志- 在版本 3.0 中更改: 添加了 - pgettext和- npgettext。- 在 2.5 版中添加: 添加了新式 gettext 支持。 
- jinja2.Environment.uninstall_gettext_translations()¶
- 卸载环境的全局安装翻译。 
- jinja2.Environment.extract_translations(source)¶
- 从给定的模板节点或源中提取可本地化的字符串。 - 对于找到的每个字符串,此函数会生成一个 - (lineno, function, message)元组,其中- lineno是找到字符串的行号。
- function是使用的- gettext函数的名称(如果字符串是从嵌入式 Python 代码中提取的)。
- message是字符串本身,或对于具有多个参数的函数,是字符串的元组。
 
对于以多种语言提供但向所有用户提供相同语言的 Web 应用程序(例如,为法语社区安装的多语言论坛软件),可以在创建环境时安装翻译。
translations = get_gettext_translations()
env = Environment(extensions=["jinja2.ext.i18n"])
env.install_gettext_translations(translations)
get_gettext_translations 函数将返回当前配置的翻译器,例如通过使用 gettext.find。
模板设计人员对 i18n 扩展的使用已在 模板文档 中介绍。
空格修剪¶
变更日志
在 2.10 版中添加。
在 {% trans %} 块中,修剪换行符和空格可能很有用,以便文本块在翻译文件中看起来像一个简单的字符串,其中只有一个空格。
可以通过启用 ext.i18n.trimmed 策略 来自动修剪换行符和周围的空格。
新式 Gettext¶
变更日志
在 2.5 版中添加。
新式 gettext 调用输入更少,出错可能性更低,并且更好地支持自动转义。
您可以通过设置 env.newstyle_gettext = True 或将 newstyle=True 传递给 env.install_translations 来使用“新样式”gettext 调用。Babel 提取工具完全支持它们,但可能无法与其他提取工具一起按预期工作。
使用标准 gettext 调用时,字符串格式化是使用 |format 过滤器完成的单独步骤。这需要为 ngettext 调用重复工作。
{{ gettext("Hello, World!") }}
{{ gettext("Hello, %(name)s!")|format(name=name) }}
{{ ngettext(
       "%(num)d apple", "%(num)d apples", apples|count
   )|format(num=apples|count) }}
{{ pgettext("greeting", "Hello, World!") }}
{{ npgettext(
       "fruit", "%(num)d apple", "%(num)d apples", apples|count
   )|format(num=apples|count) }}
新样式 gettext 使格式化成为调用的一部分,并在后台强制执行更多一致性。
{{ gettext("Hello, World!") }}
{{ gettext("Hello, %(name)s!", name=name) }}
{{ ngettext("%(num)d apple", "%(num)d apples", apples|count) }}
{{ pgettext("greeting", "Hello, World!") }}
{{ npgettext("fruit", "%(num)d apple", "%(num)d apples", apples|count) }}
新样式 gettext 的优点是
- 没有单独的格式化步骤,您不必记住使用 - |format过滤器。
- 仅允许命名占位符。这解决了翻译人员面临的一个常见问题,因为位置占位符无法有意义地切换位置。命名占位符始终携带有关哪个值位于何处的语义信息。 
- 即使不使用占位符,也会使用字符串格式化,这使得所有字符串都使用一致的格式。请记住将任何原始百分号转义为 - %%,例如- 100%%。
- 已翻译的字符串被标记为安全,格式化会根据需要执行转义。如果参数已转义,请将其标记为 - |safe。
表达式语句¶
导入名称: jinja2.ext.do
“do”又名表达式语句扩展向模板引擎添加了一个简单的 do 标记,该标记的工作方式类似于变量表达式,但会忽略返回值。
循环控件¶
导入名称: jinja2.ext.loopcontrols
此扩展为循环中的 break 和 continue 添加了支持。启用后,Jinja 提供这两个关键字,其工作方式与 Python 中完全相同。
With 语句¶
导入名称: jinja2.ext.with_
变更日志
2.9 版中已更改: 此扩展现在已内置,不再执行任何操作。
自动转义扩展¶
导入名称: jinja2.ext.autoescape
变更日志
2.9 版中已更改:此扩展已移除,现已内置。启用扩展不再执行任何操作。
调试扩展¶
导入名称: jinja2.ext.debug
添加 {% debug %} 标记以转储当前上下文以及可用的过滤器和测试。这有助于查看模板中可用的内容,而无需设置调试器。
编写扩展¶
通过编写扩展,可以向 Jinja 添加自定义标记。这是一项非平凡的任务,通常不需要,因为默认标记和表达式涵盖了所有常见用例。i18n 扩展很好地说明了扩展为何有用。另一个例子是片段缓存。
在编写扩展时,必须记住,你正在使用 Jinja 模板编译器,它不会验证你传递给它的节点树。如果 AST 格式错误,你将得到各种编译器或运行时错误,这些错误很难调试。务必正确使用创建的节点。下面的 API 文档显示了哪些节点存在以及如何使用它们。
扩展示例¶
缓存¶
以下示例通过使用 cachelib 库为 Jinja 实现了一个 cache 标记
from jinja2 import nodes
from jinja2.ext import Extension
class FragmentCacheExtension(Extension):
    # a set of names that trigger the extension.
    tags = {"cache"}
    def __init__(self, environment):
        super().__init__(environment)
        # add the defaults to the environment
        environment.extend(fragment_cache_prefix="", fragment_cache=None)
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'cache'`` so this will be a name token with
        # `cache` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = next(parser.stream).lineno
        # now we parse a single expression that is used as cache key.
        args = [parser.parse_expression()]
        # if there is a comma, the user provided a timeout.  If not use
        # None as second parameter.
        if parser.stream.skip_if("comma"):
            args.append(parser.parse_expression())
        else:
            args.append(nodes.Const(None))
        # now we parse the body of the cache block up to `endcache` and
        # drop the needle (which would always be `endcache` in that case)
        body = parser.parse_statements(["name:endcache"], drop_needle=True)
        # now return a `CallBlock` node that calls our _cache_support
        # helper method on this extension.
        return nodes.CallBlock(
            self.call_method("_cache_support", args), [], [], body
        ).set_lineno(lineno)
    def _cache_support(self, name, timeout, caller):
        """Helper callback."""
        key = self.environment.fragment_cache_prefix + name
        # try to load the block from the cache
        # if there is no fragment in the cache, render it and store
        # it in the cache.
        rv = self.environment.fragment_cache.get(key)
        if rv is not None:
            return rv
        rv = caller()
        self.environment.fragment_cache.add(key, rv, timeout)
        return rv
以下是如何在环境中使用它
from jinja2 import Environment
from cachelib import SimpleCache
env = Environment(extensions=[FragmentCacheExtension])
env.fragment_cache = SimpleCache()
在模板中,可以将块标记为可缓存。以下示例将边栏缓存 300 秒
{% cache 'sidebar', 300 %}
<div class="sidebar">
    ...
</div>
{% endcache %}
内联 gettext¶
以下示例演示了如何使用 Extension.filter_stream() 来解析对 _() gettext 函数的调用,使其与静态数据内联,而无需 Jinja 块。
<h1>_(Welcome)</h1>
<p>_(This is a paragraph)</p>
它需要加载并配置 i18n 扩展。
import re
from jinja2.exceptions import TemplateSyntaxError
from jinja2.ext import Extension
from jinja2.lexer import count_newlines
from jinja2.lexer import Token
_outside_re = re.compile(r"\\?(gettext|_)\(")
_inside_re = re.compile(r"\\?[()]")
class InlineGettext(Extension):
    """This extension implements support for inline gettext blocks::
        <h1>_(Welcome)</h1>
        <p>_(This is a paragraph)</p>
    Requires the i18n extension to be loaded and configured.
    """
    def filter_stream(self, stream):
        paren_stack = 0
        for token in stream:
            if token.type != "data":
                yield token
                continue
            pos = 0
            lineno = token.lineno
            while True:
                if not paren_stack:
                    match = _outside_re.search(token.value, pos)
                else:
                    match = _inside_re.search(token.value, pos)
                if match is None:
                    break
                new_pos = match.start()
                if new_pos > pos:
                    preval = token.value[pos:new_pos]
                    yield Token(lineno, "data", preval)
                    lineno += count_newlines(preval)
                gtok = match.group()
                if gtok[0] == "\\":
                    yield Token(lineno, "data", gtok[1:])
                elif not paren_stack:
                    yield Token(lineno, "block_begin", None)
                    yield Token(lineno, "name", "trans")
                    yield Token(lineno, "block_end", None)
                    paren_stack = 1
                else:
                    if gtok == "(" or paren_stack > 1:
                        yield Token(lineno, "data", gtok)
                    paren_stack += -1 if gtok == ")" else 1
                    if not paren_stack:
                        yield Token(lineno, "block_begin", None)
                        yield Token(lineno, "name", "endtrans")
                        yield Token(lineno, "block_end", None)
                pos = match.end()
            if pos < len(token.value):
                yield Token(lineno, "data", token.value[pos:])
        if paren_stack:
            raise TemplateSyntaxError(
                "unclosed gettext expression",
                token.lineno,
                stream.name,
                stream.filename,
            )
扩展 API¶
扩展¶
扩展始终必须扩展 jinja2.ext.Extension 类
- class jinja2.ext.Extension(environment)¶
- 扩展可用于在解析器级别向 Jinja 模板系统添加额外的功能。自定义扩展与环境绑定,但不得在 - self上存储特定于环境的数据。原因在于通过创建副本并重新分配- environment属性,可以将扩展绑定到另一个环境(用于叠加)。- 由于扩展是由环境创建的,因此它们不能接受任何配置参数。有人可能希望通过使用工厂函数来解决此问题,但这是不可能的,因为扩展是通过其导入名称来标识的。配置扩展的正确方法是将配置值存储在环境中。由于通过这种方式,环境最终充当集中配置存储,因此属性可能会冲突,这就是为什么扩展必须确保它们为配置选择的名称不太通用。例如, - prefix是一个糟糕的名称,而- fragment_cache_prefix则是一个好名称,因为它包含扩展的名称(片段缓存)。- 参数:
- environment (Environment) 
 - identifier¶
- 扩展的标识符。这始终是扩展类的真实导入名称,且不得更改。 
 - tags¶
- 如果扩展实现了自定义标签,则这是一组扩展正在侦听的标签名称。 
 - preprocess(source, name, filename=None)¶
- 此方法在实际词法分析之前调用,可用于预处理源。 - filename是可选的。返回值必须是预处理的源。
 - filter_stream(stream)¶
- 它传递了一个 - TokenStream,可用于过滤返回的标记。此方法必须返回一个- Token的可迭代对象,但它不必返回一个- TokenStream。- 参数:
- stream (TokenStream) 
- 返回类型:
 
 - attr(名称, 行号=无)¶
- 为当前扩展返回一个属性节点。这有助于将扩展中的常量传递到生成的模板代码中。 - self.attr('_my_attribute', lineno=lineno) - 参数:
- 返回类型:
 
 
解析器¶
传递给 Extension.parse() 的解析器提供了解析不同类型表达式的途径。扩展可以使用以下方法
- class jinja2.parser.Parser(environment, source, name=None, filename=None, state=None)¶
- 这是 Jinja 使用的核心解析类。它传递给扩展,可用于解析表达式或语句。 - 参数:
- environment (Environment) 
- source (str) 
- name (str | None) 
- filename (str | None) 
- state (str | None) 
 
 - name¶
- 模板的加载名称。 
 - stream¶
- 当前 - TokenStream
 - fail(msg, lineno=None, exc=TemplateSyntaxError)¶
- 使用消息、传递的行号或最后一行号以及当前名称和文件名引发 - exc的便捷方法。- 参数:
- msg (str) 
- 行号 (int | 无) 
- exc (Type[TemplateSyntaxError]) 
 
- 返回类型:
- te.NoReturn 
 
 - free_identifier(lineno=None)¶
- 返回一个新的自由标识符作为 - InternalName。- 参数:
- 行号 (int | 无) 
- 返回类型:
 
 - parse_statements(end_tokens, drop_needle=False)¶
- 解析多个语句,直至达到其中一个结束标记。这用于解析语句的主体,因为它还会在适当的情况下解析模板数据。解析器首先检查当前标记是否为冒号,如果有冒号,则跳过它。然后,它检查块结束,并解析,直至达到 - end_tokens之一。默认情况下,调用结束时的流中的活动标记是匹配的结束标记。如果不需要这样做,则可以将- drop_needle设置为- True,并且将删除结束标记。
 - parse_assign_target(with_tuple=True, name_only=False, extra_end_rules=None, with_namespace=False)¶
- 解析赋值目标。由于 Jinja 允许对元组进行赋值,因此此函数可以解析所有允许的赋值目标。默认情况下,解析对元组的赋值,但可以通过将 - with_tuple设置为- False来禁用此功能。如果仅需要对名称进行赋值,则可以将- name_only设置为- True。- extra_end_rules参数会被转发到元组解析函数。如果启用了- with_namespace,则可以解析命名空间赋值。
 - parse_expression(with_condexpr=True)¶
- 解析表达式。默认情况下,所有表达式都会被解析,如果可选的 - with_condexpr参数设置为- False,则不会解析条件表达式。
 - parse_tuple(simplified=False, with_condexpr=True, extra_end_rules=None, explicit_parentheses=False)¶
- 作用类似于 - parse_expression,但如果多个表达式用逗号分隔,则会创建一个- Tuple节点。如果未找到逗号,此方法还可以返回一个正则表达式而不是元组。- 默认解析模式是一个完整元组。如果 - simplified为- True,则只解析名称和文本。- no_condexpr参数会转发到- parse_expression()。- 由于元组不需要分隔符,并且可能以虚假逗号结尾,因此需要额外的提示来标记元组的结尾。例如,for 循环支持 - for和- in之间的元组。在这种情况下,- extra_end_rules设置为- ['name:in']。- 如果解析是由括号中的表达式触发的,则 - explicit_parentheses为真。这用于判断空元组是否为有效表达式。
 
- 类 jinja2.lexer.TokenStream(生成器, 名称, 文件名)¶
- 令牌流是一个可迭代的,它产生 - Token。然而,解析器不会对其进行迭代,而是调用- next()以向前获取一个令牌。当前活动令牌存储为- current。- expect(expr)¶
- 期望给定的标记类型并返回它。这接受与 - jinja2.lexer.Token.test()相同的参数。
 
- class jinja2.lexer.Token(lineno, type, value)¶
- 
- lineno¶
- 令牌的行号 
 - type¶
- 令牌的类型。此字符串是内部的,因此可以使用 - is运算符将其与任意字符串进行比较。
 - value¶
- 令牌的值。 
 - test(expr)¶
- 根据令牌表达式测试令牌。这可以是令牌类型或 - 'token_type:token_value'。这只能针对字符串值和类型进行测试。
 
lexer 模块中还有一个实用函数,可以计算字符串中的换行符数量
AST¶
解析后,AST(抽象语法树)用于表示模板。它由编译器随后转换为可执行 Python 代码对象的节点构建。提供自定义语句的扩展可以返回节点以执行自定义 Python 代码。
以下列表描述了当前可用的所有节点。AST 可能会在 Jinja 版本之间更改,但会保持向后兼容。
有关更多信息,请查看 jinja2.Environment.parse() 的 repr。
- class jinja2.nodes.Node¶
- 所有 Jinja 节点的基类。有许多不同类型的可用节点。有四种主要类型 - 所有节点都有字段和属性。字段可以是其他节点、列表或任意值。字段作为常规位置参数传递给构造函数,属性作为关键字参数传递。每个节点有两个属性: - lineno(节点的行号)和- environment。对于所有节点,- environment属性会在解析过程的末尾自动设置。- iter_fields(exclude=None, only=None)¶
- 此方法迭代所有已定义的字段并生成 - (key, value)元组。默认情况下,将返回所有字段,但可以通过提供- only参数或使用- exclude参数排除一些字段来将返回结果限制为某些字段。这两个参数都应是字段名称的集合或元组。
 - iter_child_nodes(exclude=None, only=None)¶
- 迭代节点的所有直接子节点。此方法迭代所有字段,并生成其值为节点的字段。如果字段的值是列表,则返回该列表中的所有节点。 
 - 查找全部(node_type)¶
- 查找给定类型的所有节点。如果类型为元组,则对元组项中的任何项执行检查。 
 - 设置上下文(ctx)¶
- 重置节点及其所有子节点的上下文。默认情况下,解析器将生成所有具有“加载”上下文的节点,因为它是其中最常见的。此方法在解析器中用于将赋值目标和其他节点设置为存储上下文。 
 - set_environment(environment)¶
- 为所有节点设置环境。 - 参数:
- environment (Environment) 
- 返回类型:
 
 
- class jinja2.nodes.Expr¶
- 所有表达式的基类。 - as_const(eval_ctx=None)¶
- 返回表达式的值作为常量,或在不可能时引发 - Impossible。- 可以提供 - EvalContext,如果没有提供,则创建一个默认上下文,该上下文要求节点具有附加的环境。- 变更日志- 2.4 版中已更改: 添加了 - eval_ctx参数。- 参数:
- eval_ctx (EvalContext | None) 
- 返回类型:
 
 
- 类 jinja2.nodes._FilterTestCommon(节点, 名称, 参数, 关键字参数, 动态参数, 动态关键字参数)¶
- 类 jinja2.nodes.Filter(节点, 名称, 参数, 关键字参数, 动态参数, 动态关键字参数)¶
- 将过滤器应用于表达式。 - 名称是过滤器的名称,其他字段与- Call相同。- 如果 - 节点是- None,则过滤器正在过滤器块中使用,并应用于块的内容。- 节点类型:
- 参数:
 
- 类 jinja2.nodes.Test(节点, 名称, 参数, 关键字参数, 动态参数, 动态关键字参数)¶
- 将测试应用于表达式。 - 名称是测试的名称,其他字段与- Call相同。- 变更日志- 3.0 版中已更改: - as_const对过滤器和测试共享相同的逻辑。测试检查不稳定、异步和- @pass_context等装饰器。- 节点类型:
- 参数:
 
- class jinja2.nodes.FloorDiv(left, right)¶
- 将左侧除以右侧节点,并将结果截断转换为整数。 
- 类 jinja2.nodes.Call(节点, 参数, 关键字参数, 动态参数, 动态关键字参数)¶
- 调用表达式。 - args是参数列表,- kwargs是关键字参数列表(- Keyword节点的列表),并且- dyn_args和- dyn_kwargs必须是- None或用作动态位置(- *args)或关键字(- **kwargs)参数的节点。
- 类 jinja2.nodes.Concat(节点)¶
- 将提供的表达式列表连接起来,在将它们转换为字符串后进行连接。 
- class jinja2.nodes.CondExpr(test, expr1, expr2)¶
- 条件表达式(内联 if 表达式)。( - {{ foo if bar else baz }})
- class jinja2.nodes.ContextReference¶
- 返回当前模板上下文。它可以像 - Name节点一样使用,具有- 'load'ctx,并将返回当前- Context对象。- 这是一个示例,将当前模板名称分配给名为 - foo的变量- Assign(Name('foo', ctx='store'), Getattr(ContextReference(), 'name')) - 这基本上等同于在使用高级 API 时使用 - pass_context()装饰器,这会导致将对上下文的引用作为第一个参数传递给函数。
- class jinja2.nodes.DerivedContextReference¶
- 返回包括本地变量的当前模板上下文。行为与 - ContextReference完全相同,但包括本地变量,例如来自- for循环。- 变更日志- 在版本 2.11 中添加。 
- class jinja2.nodes.EnvironmentAttribute(name)¶
- 加载环境对象的属性。这对于想要调用存储在环境中的回调的扩展很有用。 
- 类 jinja2.nodes.ExtensionAttribute(标识符, 名称)¶
- 返回与环境绑定的扩展的属性。标识符是 - Extension的标识符。- 此节点通常通过调用扩展上的 - attr()方法来构造。
- 类 jinja2.nodes.Getattr(节点, attr, ctx)¶
- 从表达式中获取一个属性或项,该表达式是仅包含 ASCII 字符的字节串,并且优先使用该属性。 
- 类 jinja2.nodes.Getitem(节点, arg, ctx)¶
- 从表达式中获取一个属性或项,并且优先使用该项。 
- 类 jinja2.nodes.ImportedName(导入名称)¶
- 如果使用导入名称创建,则在节点访问时返回导入名称。例如 - ImportedName('cgi.escape')在评估时从 cgi 模块返回- escape函数。导入由编译器优化,因此无需将它们分配给局部变量。
- 类 jinja2.nodes.InternalName(name)¶
- 编译器中的内部名称。您不能自己创建这些节点,但解析器提供了一个 - free_identifier()方法,该方法为您创建一个新的标识符。编译器无法从模板中获取此标识符,也不会对其进行特殊处理。- 节点类型:
 
- 类 jinja2.nodes.Const(value)¶
- 所有常量值。解析器将为 - 42或- "foo"等简单常量返回此节点,但它也可用于存储更复杂的值,例如列表。只有具有安全表示形式的常量(对象,其中- eval(repr(x)) == x为真)。
- class jinja2.nodes.MarkSafe(expr)¶
- 将包装的表达式标记为安全(将其包装为 - Markup)。
- class jinja2.nodes.MarkSafeIfAutoescape(expr)¶
- 将包装的表达式标记为安全(将其包装为 - Markup),但仅当自动转义处于活动状态时才标记。- 变更日志- 在 2.5 版中添加。 
- class jinja2.nodes.Name(name, ctx)¶
- 查找名称或在名称中存储值。节点的 - ctx可以是以下值之一- store:在名称中存储值
- load:加载该名称
- param:与- store相同,但如果名称定义为函数参数。
 
- class jinja2.nodes.Slice(start, stop, step)¶
- 表示切片对象。这只能用作 - Subscript的参数。
- 类 jinja2.nodes.Pos(node)¶
- 使表达式变为正数(对于大多数表达式来说是空操作) 
- 类 jinja2.nodes.Keyword(key, value)¶
- 关键字参数的键值对,其中键是一个字符串。 
- 类 jinja2.nodes.AssignBlock(target, filter, body)¶
- 将块分配给目标。 
- 类 jinja2.nodes.Block(name, body, scoped, required)¶
- 表示块的节点。 - 变更日志- 在版本 3.0.0 中更改:添加了 - required字段。
- 类 jinja2.nodes.CallBlock(call, args, defaults, body)¶
- 就像一个没有名称但有调用的宏。 - call被称为- caller参数,此节点持有该参数作为未命名宏。
- class jinja2.nodes.EvalContextModifier(options)¶
- 修改 eval 上下文。对于应该修改的每个选项,必须将 - Keyword添加到- options列表。- 更改 - autoescape设置的示例- EvalContextModifier(options=[Keyword('autoescape', Const(True))]) 
- class jinja2.nodes.ScopedEvalContextModifier(options, body)¶
- 修改 eval 上下文并在稍后还原。其工作原理与 - EvalContextModifier完全相同,但只会修改- body中节点的- EvalContext。- 节点类型:
- 参数:
 
- 类 jinja2.nodes.For(目标, 迭代器, 正文, else_, 测试, 递归)¶
- for 循环。 - 目标是迭代的目标(通常是- Name或- Tuple),- 迭代器是可迭代对象。- 正文是用作循环正文的节点列表,- else_是- else块的节点列表。如果不存在 else 节点,则它必须是一个空列表。- 对于经过过滤的节点,可以将表达式存储为 - 测试,否则为- 无。
- 类 jinja2.nodes.FromImport(模板, 名称, 带上下文)¶
- 表示 from import 标记的节点。重要的是不要将不安全名称传递给 name 属性。编译器直接将属性查找翻译为 getattr 调用,不使用接口的脚本回调。由于导出的变量可能不以双下划线开头(解析器断言),因此对于常规 Jinja 代码来说这不是问题,但是如果此节点用于扩展,则必须格外小心。 - 如果需要别名,名称列表可能包含元组。 
- class jinja2.nodes.If(test, body, elif_, else_)¶
- 如果 - test为真,则渲染- body,否则渲染- else_。
- class jinja2.nodes.Import(template, target, with_context)¶
- 表示 import 标记的节点。 
- class jinja2.nodes.Include(template, with_context, ignore_missing)¶
- 表示 include 标记的节点。 
- class jinja2.nodes.Macro(name, args, defaults, body)¶
- 宏定义。 - name是宏的名称,- args是参数列表,- defaults是默认值列表(如果有)。- body是宏主体节点的列表。
- class jinja2.nodes.Output(nodes)¶
- 一个包含多个表达式并随后打印它们的节点。这用于 - print语句和常规模板数据。
- class jinja2.nodes.OverlayScope(context, body)¶
- 扩展的覆盖范围。这是一个在很大程度上未经优化的范围,但可以用于从字典或类似字典的对象中向子范围引入完全任意的变量。 - context字段必须评估为一个字典对象。- 示例用法 - OverlayScope(context=self.call_method('get_context'), body=[...]) - 变更日志- 在 2.10 版中添加。 
- class jinja2.nodes.With(targets, values, body)¶
- with 语句的特定节点。在旧版本的 Jinja 中,with 语句是基于 - Scope节点实现的。- 变更日志- 在 2.9.3 版本中添加。 
- class jinja2.nodes.Template(body)¶
- 表示模板的节点。这必须传递给编译器的最外层节点。 
- exception jinja2.nodes.Impossible¶
- 如果节点无法执行请求的操作,则引发此异常。 
