访问父级循环

最后更新于:2022-04-01 04:05:14

特殊的 loop 变量总是指向最里层的循环。如果想要访问外层的循环,可以给它 设置别名: ~~~ <table> {% for row in table %} <tr> {% set rowloop = loop %} {% for cell in row %} <td id="cell-{{ rowloop.index }}-{{ loop.index }}>{{ cell }}</td> {% endfor %} </tr> {% endfor %} </table> ~~~
';

高亮活动菜单项

最后更新于:2022-04-01 04:05:12

你经常想要一个带有活动导航项的导航栏。这相当容易实现。因为在 block 外 的声明在子模板中是全局的,并且在布局模板求值前执行,在子模板中定义活动的 菜单项: ~~~ {% extends "layout.html" %} {% set active_page = "index" %} ~~~ 布局模板之后就可以访问 active_page 。此外,这意味着你可以为它定义默认 值: ~~~ {% set navigation_bar = [ ('/', 'index', 'Index'), ('/downloads/', 'downloads', 'Downloads'), ('/about/', 'about', 'About') ] -%} {% set active_page = active_page|default('index') -%} ... <ul id="navigation"> {% for href, id, caption in navigation_bar %} <li{% if id == active_page %} class="active"{% endif %}><a href="{{ href|e }}">{{ caption|e }}</a>/li> {% endfor %} </ul> ... ~~~
';

交替的行

最后更新于:2022-04-01 04:05:10

如果你想要对一个表格或列表中的每行使用不同的样式,可以使用 loop 对象的 cycle 方法: ~~~ <ul> {% for row in rows %} <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li> {% endfor %} </ul> ~~~ cycle 可接受无限数目的字符串。每次遭遇这个标签,列表中的下一项 就会被渲染。
';

Null-Master 退回

最后更新于:2022-04-01 04:05:08

Jinja2 支持动态继承并且只要没有 extends 标签被访问过,就不分辨父模板和子模 板。而这会导致令人惊讶的行为:首个 extends 标签前的包括空白字符的所有东西 会被打印出来而不是被忽略,这也可以用作一个巧妙的方法。 通常,继承一个模板的子模板来添加基本的 HTML 骨架。而把 extends 标签放在 if 标签中,当 standalone 变量值为 false 时(按照默认未定义也为 false )继 承布局模板是可行的。此外,一个非常基本的骨架会被添加到文件,这样如果确实带 置为 True 的standalone 渲染,一个非常基本的 HTML 骨架会被添加: ~~~ {% if not standalone %}{% extends 'master.html' %}{% endif -%} <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <title>{% block title %}The Page Title{% endblock %}</title> <link rel="stylesheet" href="style.css" type="text/css"> {% block body %} <p>This is the page body.</p> {% endblock %} ~~~
';

提示和技巧

最后更新于:2022-04-01 04:05:05

这部分文档展示了一些 Jinja2 模板的提示和技巧。
';

Mako

最后更新于:2022-04-01 04:05:03

如果你迄今使用 Mako 并且想要转换到 Jinja2 ,你可以把 Jinja2 配置成 Mako 一 样: ~~~ env = Environment('<%', '%>', '${', '}', '%') ~~~ 环境配置成这样后, Jinja2 应该可以解释一个 Mako 模板的小型子集。 Jinja2 不支持 嵌入 Python 代码,所以你可能需要把它们移出模板。 def 的语法(在 Jinja2 中 def 被叫做宏)并且模板继承也是不同的。下面的 Mako 模板: ~~~ <%inherit file="layout.html" /> <%def name="title()">Page Title</%def> <ul> % for item in list: <li>${item}</li> % endfor </ul> ~~~ 在以上配置的 Jinja2 中看起来是这样: ~~~ <% extends "layout.html" %> <% block title %>Page Title<% endblock %> <% block body %> <ul> % for item in list: <li>${item}</li> % endfor </ul> <% endblock %> ~~~
';

Django

最后更新于:2022-04-01 04:05:01

如果你之前使用 Django 模板,你应该会发现跟 Jinja2 非常相似。实际上, 很多的语法元素看起来相同,工作也相同。 尽管如此, Jinja2 提供了更多的在之前文档中描述的语法元素,并且某些 工作会有一点不一样。 本节介绍了模板差异。由于 API 是从根本上不同,我们不会再这里赘述。 ### 方法调用[](http://docs.jinkan.org/docs/jinja2/switching.html#id3 "Permalink to this headline") 在 Django 中,方法调用是隐式的。在 Jinja2 中,你必须指定你要调用一个对象。如 此,这段 Django 代码: ~~~ {% for page in user.get_created_pages %} ... {% endfor %} ~~~ 在 Jinja 中应该是这样: ~~~ {% for page in user.get_created_pages() %} ... {% endfor %} ~~~ 这允许你给函数传递变量,且宏也使用这种方式,而这在 Django 中是不可能的。 ### 条件[](http://docs.jinkan.org/docs/jinja2/switching.html#id4 "Permalink to this headline") 在 Django 中你可以使用下面的结构来判断是否相等: ~~~ {% ifequal foo "bar" %} ... {% else %} ... {% endifequal %} ~~~ 在 Jinja2 中你可以像通常一样使用 if 语句和操作符来做比较: ~~~ {% if foo == 'bar' %} ... {% else %} ... {% endif %} ~~~ 你也可以在模板中使用多个 elif 分支: ~~~ {% if something %} ... {% elif otherthing %} ... {% elif foothing %} ... {% else %} ... {% endif %} ~~~ ### 过滤器参数[](http://docs.jinkan.org/docs/jinja2/switching.html#id5 "Permalink to this headline") Jinja2 为过滤器提供不止一个参数。参数传递的语法也是不同的。一个这样的 Django 模板: ~~~ {{ items|join:", " }} ~~~ 在 Jinja2 中是这样: ~~~ {{ items|join(', ') }} ~~~ 实际上这有点冗赘,但它允许不同类型的参数——包括变量——且不仅是一种。 ### 测试[](http://docs.jinkan.org/docs/jinja2/switching.html#id6 "Permalink to this headline") 除过滤器外,同样有用 is 操作符运行的测试。这里是一些例子: ~~~ {% if user.user_id is odd %} {{ user.username|e }} is odd {% else %} hmm. {{ user.username|e }} looks pretty normal {% endif %} ~~~ ### 循环[](http://docs.jinkan.org/docs/jinja2/switching.html#id7 "Permalink to this headline") 因为循环与 Django 中的十分相似,仅有的不兼容是 Jinja2 中循环上下文的特殊变 量名为loop 而不是 Django 中的 forloop 。 ### 周期计[](http://docs.jinkan.org/docs/jinja2/switching.html#id8 "Permalink to this headline") Jinja 中没有 {% cycle %} 标签,因为它是隐式的性质。而你可以用循环对象 的 cycle 方法实现几乎相同的东西。 下面的 Django 模板: ~~~ {% for user in users %} <li class="{% cycle 'odd' 'even' %}">{{ user }}</li> {% endfor %} ~~~ Jinja 中看起来是这样: ~~~ {% for user in users %} <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li> {% endfor %} ~~~ 没有与 {% cycle ... as variable %} 等价的。
';

Jinja1

最后更新于:2022-04-01 04:04:58

Jinja2 与 Jinja1 在 API 使用和模板语法上最为兼容。下面的列表解释了 Jinja1 和 Jinja2 的区别。 ### API[](http://docs.jinkan.org/docs/jinja2/switching.html#api "Permalink to this headline") 加载器 Jinja2 使用不同的加载器 API 。因为模板的内部表示更改,不再支持 memcached 这样的外部缓存系统。模板的内存开销与常规的 Python 模块相当,外部缓存不能 带来优势。如果你以前使用了一个自定义的加载器,请阅读 [*loader API*](http://docs.jinkan.org/docs/jinja2/api.html#loaders) 部分。 从字符串加载模板 在过去,在默认环境配置中使用 jinja.from_string 从字符串生成模板是可能 的。 Jinja2 提供了一个 Template 类来用于做同样的事情,但是需要 可选的额外配置。 自动 Unicode 转换 Jinja1 执行把字节串从一个给定编码到 unicode 对象的自动转换。这个转换不再 被实现,因为它与大多数使用常规 Python ASCII 字节串到 Unicode 转换的库不 一致。一个由 Jinja2 驱动的应用 *必须* 在内部的每个地方都使用 unicode 或 确保 Jinja2 只会被传递 unicode 字符串。 i18n Jinja1 使用自定义的国际化翻译器。 i18n 现在作为 Jinja2 的一个扩展,并且 使用更简单、更 gettext 友好的接口,并且支持 babel 。更多细节见 [*i18n 扩展*](http://docs.jinkan.org/docs/jinja2/extensions.html#i18n-extension) 。 内部方法 Jinja1 在环境对象上暴露了诸如 call_function 、 get_attribute 等内部 方法。当它们被标记为一个内部方法,则可以覆盖它们。 Jinja2 并没有等价的 方法。 沙箱 Jinja1 默认运行沙箱模式。实际上只有少数应用使用这一特性,所以这在 Jinja2 中是可选的。更多关于上下执行的细节见 SandboxedEnvironment 。 上下文 Jinja1 有一个上下文栈存储传递到环境的变量。在 Jinja2 中有一个类似的 对象,但它不允许修改也不是单例的。由于继承是动态的,现在当模板求值时 可能存在多个上下文对象。 过滤器和测试 过滤器和测试现在是常规的函数。不再允许使用工厂函数,且也没有必要。 ### 模板[](http://docs.jinkan.org/docs/jinja2/switching.html#id2 "Permalink to this headline") Jinja2 与 Jinja1 的语法几乎相同。区别是,现在宏需要用小括号包裹参数。 此外, Jinja2 允许动态继承和动态包含。老的辅助函数 rendertemplate 作古, 而使用include 。包含不再导入宏和变量声明,因为采用了新的 import 标签。 这个概念在 [*导入*](http://docs.jinkan.org/docs/jinja2/templates.html#import)文档中做了解释。 另一个改变发生在 for 标签里。特殊的循环变量不再拥有 parent 属性,而 你需要自己给循环起别名。见 [*访问父级循环*](http://docs.jinkan.org/docs/jinja2/tricks.html#accessing-the-parent-loop) 了解更多细节。
';

从其它的模板引擎切换

最后更新于:2022-04-01 04:04:56

如果你过去使用一个不同的模板引擎,并且想要转换到 Jinja2 ,这里是一份简小的 指导展示了一些常见的、相似的 Python 文本模板引擎基本语法和语义差异
';

Vim

最后更新于:2022-04-01 04:04:54

同样,在 Jinja2 项目的根目录下的 ext 文件夹中的 Vim-scripts 目录有一个 [Vim](http://www.vim.org/) 的语法插件。 [这个脚本](http://www.vim.org/scripts/script.php?script_id=1856) 支持 Jinja1 和 Jinja2 。安装后, jinja 和 htmljinja 两种文件类型可用。前者 给基于文本的模板,后者给 HTML 模板。 把这些文件复制到你的 syntax 文件夹。
';

TextMate

最后更新于:2022-04-01 04:04:52

在 Jinja2 项目根目录的 ext 文件夹中,有一个 TextMate 的 bundle 来提供 Jinja1 和 Jinja2 的基于文本的模板的语法高亮,同样也支持 HTML 。它也包含了一些常用的片 段。
';

Pylons

最后更新于:2022-04-01 04:04:49

从 [Pylons](http://www.pylonshq.com/) 0.9.7 开始,集成 Jinja 到 Pylons 驱动的应用令人难以置信的简单。 模板引擎在 config/environment.py 中配置。为 Jinja2 的配置看起来是这样: ~~~ from jinja2 import Environment, PackageLoader config['pylons.app_globals'].jinja_env = Environment( loader=PackageLoader('yourapplication', 'templates') ) ~~~ 之后,你可以用 pylons.templating 模块中的 render_jinja 函数渲染 Jinja 模板。 此外,设置 Pylons 的 c 对象为严格模式是个好主意。按照默认,访问任何 c 对象 上不存在的属性会返回一个空字符串而不是一个未定义对象。更改这个,只需要使用这个 片段并添加到你的 config/environment.py 中: ~~~ config['pylons.strict_c'] = True ~~~
';

Babel 集成

最后更新于:2022-04-01 04:04:47

Jinja 提供了用 [Babel](http://babel.edgewall.org/) 抽取器从模板中抽取 gettext 消息的支持,抽取器的接入点 名为jinja2.ext.babel_extract 。 Babel 支持的被作为 [*i18n 扩展*](http://docs.jinkan.org/docs/jinja2/extensions.html#i18n-extension) 的 一部分实现。 Gettext 消息从 trans 标签和代码表达式中抽取。 要从模板中抽取 gettext 消息,项目需要在它的 Babel 抽取方法 [mapping file](http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration) 中 有一个 Jinja2 节: ~~~ [jinja2: **/templates/**.html] encoding = utf-8 ~~~ Environment 的语法相关选项也可作为 mapping file 的配置值。例如告知 抽取器模板使用 %作为 line_statement_prefix 你可以这样写: ~~~ [jinja2: **/templates/**.html] encoding = utf-8 line_statement_prefix = % ~~~ [*扩展*](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja-extensions) 可能也被定义为传递一个逗号分割的导入路径列表作为 extensions 值。 i18n 扩展会被自动添加。 Changed in version 2.7: 直到 2.7 模板语法错误始终被忽略。因为许多人在模板文件夹中放置非模板的 html 文件,而这会随机报错,所以如此设定。假定是无论如何测试套件会捕获 模板中的语法错误。如果你不想要这个行为,你可以在设置中添加 slient=flase ,异常会被传播。
';

集成

最后更新于:2022-04-01 04:04:45

Jinja2 提供了一些代码来继承到其它工具,诸如框架、 [Babel](http://babel.edgewall.org/) 库或你偏好的编辑器 的奇特的代码高亮。这里是包含的这些的简要介绍。 帮助继承的文件在 [这里](https://github.com/mitsuhiko/jinja2/master/ext) 可 用。
';

编写扩展

最后更新于:2022-04-01 04:04:42

你可以编写扩展来向 Jinja2 中添加自定义标签。这是一个不平凡的任务,而且通常不需 要,因为默认的标签和表达式涵盖了所有常用情况。如 i18n 扩展是一个扩展有用的好例 子,而另一个会是碎片缓存。 当你编写扩展时,你需要记住你在与 Jinja2 模板编译器一同工作,而它并不验证你传递 到它的节点树。如果 AST 是畸形的,你会得到各种各样的编译器或运行时错误,这调试起 来极其可怕。始终确保你在使用创建正确的节点。下面的 API 文档展示了有什么节点和如 何使用它们。 ### 示例扩展[](http://docs.jinkan.org/docs/jinja2/extensions.html#id9 "Permalink to this headline") 下面的例子用 [Werkzeug](http://werkzeug.pocoo.org/) 的缓存 contrib 模块为 Jinja2 实现了一个 cache 标签: ~~~ from jinja2 import nodes from jinja2.ext import Extension class FragmentCacheExtension(Extension): # a set of names that trigger the extension. tags = set(['cache']) def __init__(self, environment): super(FragmentCacheExtension, self).__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 = parser.stream.next().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 werkzeug.contrib.cache import SimpleCache env = Environment(extensions=[FragmentCacheExtension]) env.fragment_cache = SimpleCache() ~~~ 之后,在模板中可以标记块为可缓存的。下面的例子缓存一个边栏 300 秒: ~~~ {% cache 'sidebar', 300 %} <div class="sidebar"> ... </div> {% endcache %} ~~~ ### 扩展 API[](http://docs.jinkan.org/docs/jinja2/extensions.html#api "Permalink to this headline") 扩展总是继承 [jinja2.ext.Extension](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension "jinja2.ext.Extension") 类: *class *jinja2.ext.Extension(*environment*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension "Permalink to this definition") Extensions can be used to add extra functionality to the Jinja template system at the parser level. Custom extensions are bound to an environment but may not store environment specific data on self. The reason for this is that an extension can be bound to another environment (for overlays) by creating a copy and reassigning theenvironment attribute. As extensions are created by the environment they cannot accept any arguments for configuration. One may want to work around that by using a factory function, but that is not possible as extensions are identified by their import name. The correct way to configure the extension is storing the configuration values on the environment. Because this way the environment ends up acting as central configuration storage the attributes may clash which is why extensions have to ensure that the names they choose for configuration are not too generic. prefix for example is a terrible name,fragment_cache_prefix on the other hand is a good name as includes the name of the extension (fragment cache). identifier[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.identifier "Permalink to this definition") 扩展的标识符。这始终是扩展类的真实导入名,不能被修改。 tags[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.tags "Permalink to this definition") 如果扩展实现自定义标签,这是扩展监听的标签名的集合。 attr(*name*, *lineno=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.attr "Permalink to this definition") Return an attribute node for the current extension. This is useful to pass constants on extensions to generated template code. ~~~ self.attr('_my_attribute', lineno=lineno) ~~~ call_method(*name*, *args=None*, *kwargs=None*, *dyn_args=None*,*dyn_kwargs=None*, *lineno=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.call_method "Permalink to this definition") Call a method of the extension. This is a shortcut for [attr()](http://docs.jinkan.org/docs/jinja2/templates.html#attr "attr") + [jinja2.nodes.Call](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Call "jinja2.nodes.Call"). filter_stream(*stream*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.filter_stream "Permalink to this definition") It’s passed a [TokenStream](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream "jinja2.lexer.TokenStream") that can be used to filter tokens returned. This method has to return an iterable of [Token](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token "jinja2.lexer.Token")s, but it doesn’t have to return a [TokenStream](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream "jinja2.lexer.TokenStream"). In the ext folder of the Jinja2 source distribution there is a file calledinlinegettext.py which implements a filter that utilizes this method. parse(*parser*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.parse "Permalink to this definition") If any of the [tags](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.tags "jinja2.ext.Extension.tags") matched this method is called with the parser as first argument. The token the parser stream is pointing at is the name token that matched. This method has to return one or a list of multiple nodes. preprocess(*source*, *name*, *filename=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.preprocess "Permalink to this definition") This method is called before the actual lexing and can be used to preprocess the source. The filename is optional. The return value must be the preprocessed source. ### 解析器 API[](http://docs.jinkan.org/docs/jinja2/extensions.html#id10 "Permalink to this headline") 传递到 [Extension.parse()](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.parse "jinja2.ext.Extension.parse") 的解析器提供解析不同类型表达式的方式。下 面的方法可能会在扩展中使用: *class *jinja2.parser.Parser(*environment*, *source*, *name=None*, *filename=None*,*state=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser "Permalink to this definition") This is the central parsing class Jinja2 uses. It’s passed to extensions and can be used to parse expressions or statements. filename[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Parser.filename "Permalink to this definition") 解析器处理的模板文件名。这 **不是** 模板的加载名。加载名见 [name](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Parser.name "jinja2.ext.Parser.name") 。对于不是从文件系统中加载的模板,这个值为 None 。 name[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Parser.name "Permalink to this definition") 模板的加载名。 stream[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Parser.stream "Permalink to this definition") 当前的 [TokenStream](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream "jinja2.lexer.TokenStream") 。 fail(*msg*, *lineno=None*, *exc=*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.fail "Permalink to this definition") Convenience method that raises exc with the message, passed line number or last line number as well as the current name and filename. free_identifier(*lineno=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.free_identifier "Permalink to this definition") Return a new free identifier as [InternalName](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.InternalName "jinja2.nodes.InternalName"). parse_assign_target(*with_tuple=True*, *name_only=False*,*extra_end_rules=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.parse_assign_target "Permalink to this definition") Parse an assignment target. As Jinja2 allows assignments to tuples, this function can parse all allowed assignment targets. Per default assignments to tuples are parsed, that can be disable however by setting with_tuple to False. If only assignments to names are wanted name_only can be set to True. Theextra_end_rules parameter is forwarded to the tuple parsing function. parse_expression(*with_condexpr=True*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.parse_expression "Permalink to this definition") Parse an expression. Per default all expressions are parsed, if the optionalwith_condexpr parameter is set to False conditional expressions are not parsed. parse_statements(*end_tokens*, *drop_needle=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.parse_statements "Permalink to this definition") Parse multiple statements into a list until one of the end tokens is reached. This is used to parse the body of statements as it also parses template data if appropriate. The parser checks first if the current token is a colon and skips it if there is one. Then it checks for the block end and parses until if one of the end_tokens is reached. Per default the active token in the stream at the end of the call is the matched end token. If this is not wanted drop_needle can be set to True and the end token is removed. parse_tuple(*simplified=False*, *with_condexpr=True*, *extra_end_rules=None*,*explicit_parentheses=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.parse_tuple "Permalink to this definition") Works like parse_expression but if multiple expressions are delimited by a comma a [Tuple](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Tuple "jinja2.nodes.Tuple") node is created. This method could also return a regular expression instead of a tuple if no commas where found. The default parsing mode is a full tuple. If simplified is True only names and literals are parsed. The no_condexpr parameter is forwarded toparse_expression(). Because tuples do not require delimiters and may end in a bogus comma an extra hint is needed that marks the end of a tuple. For example for loops support tuples between for and in. In that case the extra_end_rules is set to ['name:in']. explicit_parentheses is true if the parsing was triggered by an expression in parentheses. This is used to figure out if an empty tuple is a valid expression or not. *class *jinja2.lexer.TokenStream(*generator*, *name*, *filename*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream "Permalink to this definition") A token stream is an iterable that yields Tokens. The parser however does not iterate over it but calls next() to go one token ahead. The current active token is stored as[current](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.TokenStream.current "jinja2.ext.TokenStream.current"). current[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.TokenStream.current "Permalink to this definition") 当前的 [Token](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token "jinja2.lexer.Token") 。 eos[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.eos "Permalink to this definition") Are we at the end of the stream? expect(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.expect "Permalink to this definition") Expect a given token type and return it. This accepts the same argument as[jinja2.lexer.Token.test()](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token.test "jinja2.lexer.Token.test"). look()[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.look "Permalink to this definition") Look at the next token. next()[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.next "Permalink to this definition") Go one token ahead and return the old one next_if(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.next_if "Permalink to this definition") Perform the token test and return the token if it matched. Otherwise the return value is None. push(*token*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.push "Permalink to this definition") Push a token back to the stream. skip(*n=1*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.skip "Permalink to this definition") Got n tokens ahead. skip_if(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.TokenStream.skip_if "Permalink to this definition") Like next_if() but only returns True or False. *class *jinja2.lexer.Token[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token "Permalink to this definition") Token class. lineno[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Token.lineno "Permalink to this definition") token 的行号。 type[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Token.type "Permalink to this definition") token 的类型。这个值是被禁锢的,所以你可以用 is 运算符同任意字符 串比较。 value[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Token.value "Permalink to this definition") token 的值。 test(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token.test "Permalink to this definition") Test a token against a token expression. This can either be a token type or'token_type:token_value'. This can only test against string values and types. test_any(**iterable*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.lexer.Token.test_any "Permalink to this definition") Test against multiple token expressions. 同样,在词法分析模块中也有一个实用函数可以计算字符串中的换行符数目: ~~~ .. autofunction:: jinja2.lexer.count_newlines ~~~ ### AST[](http://docs.jinkan.org/docs/jinja2/extensions.html#ast "Permalink to this headline") AST(抽象语法树: Abstract Syntax Tree)用于表示解析后的模板。它有编译器之后 转换到可执行的 Python 代码对象的节点构建。提供自定义语句的扩展可以返回执行自 定义 Python 代码的节点。 下面的清单展示了所有当前可用的节点。 AST 在 Jinja2 的各个版本中有差异,但会向 后兼容。 更多信息请见 [jinja2.Environment.parse()](http://docs.jinkan.org/docs/jinja2/api.html#jinja2.Environment.parse "jinja2.Environment.parse") 。 *class *jinja2.nodes.Node[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node "Permalink to this definition") Baseclass for all Jinja2 nodes. There are a number of nodes available of different types. There are four major types: * [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt"): statements * [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr"): expressions * [Helper](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Helper "jinja2.nodes.Helper"): helper nodes * [Template](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Template "jinja2.nodes.Template"): the outermost wrapper node All nodes have fields and attributes. Fields may be other nodes, lists, or arbitrary values. Fields are passed to the constructor as regular positional arguments, attributes as keyword arguments. Each node has two attributes: lineno (the line number of the node) and environment. The environment attribute is set at the end of the parsing process for all nodes automatically. find(*node_type*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.find "Permalink to this definition") Find the first node of a given type. If no such node exists the return value isNone. find_all(*node_type*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.find_all "Permalink to this definition") Find all the nodes of a given type. If the type is a tuple, the check is performed for any of the tuple items. iter_child_nodes(*exclude=None*, *only=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.iter_child_nodes "Permalink to this definition") Iterates over all direct child nodes of the node. This iterates over all fields and yields the values of they are nodes. If the value of a field is a list all the nodes in that list are returned. iter_fields(*exclude=None*, *only=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.iter_fields "Permalink to this definition") This method iterates over all fields that are defined and yields (key, value) tuples. Per default all fields are returned, but it’s possible to limit that to some fields by providing the only parameter or to exclude some using the exclude parameter. Both should be sets or tuples of field names. set_ctx(*ctx*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.set_ctx "Permalink to this definition") Reset the context of a node and all child nodes. Per default the parser will all generate nodes that have a ‘load’ context as it’s the most common one. This method is used in the parser to set assignment targets and other nodes to a store context. set_environment(*environment*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.set_environment "Permalink to this definition") Set the environment for all nodes. set_lineno(*lineno*, *override=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node.set_lineno "Permalink to this definition") Set the line numbers of the node and children. *class *jinja2.nodes.Expr[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "Permalink to this definition") Baseclass for all expressions. Node type: [Node](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node "jinja2.nodes.Node") as_const(*eval_ctx=None*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr.as_const "Permalink to this definition") Return the value of the expression as constant or raise [Impossible](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Impossible "jinja2.nodes.Impossible") if this was not possible. An [EvalContext](http://docs.jinkan.org/docs/jinja2/api.html#jinja2.nodes.EvalContext "jinja2.nodes.EvalContext") can be provided, if none is given a default context is created which requires the nodes to have an attached environment. Changed in version 2.4: the eval_ctx parameter was added. can_assign()[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr.can_assign "Permalink to this definition") Check if it’s possible to assign something to this node. *class *jinja2.nodes.BinExpr(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "Permalink to this definition") Baseclass for all binary expressions. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Add(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Add "Permalink to this definition") Add the left to the right node. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.And(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.And "Permalink to this definition") Short circuited AND. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Div(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Div "Permalink to this definition") Divides the left by the right node. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.FloorDiv(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.FloorDiv "Permalink to this definition") Divides the left by the right node and truncates conver the result into an integer by truncating. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Mod(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Mod "Permalink to this definition") Left modulo right. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Mul(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Mul "Permalink to this definition") Multiplies the left with the right node. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Or(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Or "Permalink to this definition") Short circuited OR. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Pow(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Pow "Permalink to this definition") Left to the power of right. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Sub(*left*, *right*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Sub "Permalink to this definition") Substract the right from the left node. Node type: [BinExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.BinExpr "jinja2.nodes.BinExpr") *class *jinja2.nodes.Call(*node*, *args*, *kwargs*, *dyn_args*, *dyn_kwargs*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Call "Permalink to this definition") Calls an expression. args is a list of arguments, kwargs a list of keyword arguments (list of [Keyword](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Keyword "jinja2.nodes.Keyword") nodes), and dyn_args and dyn_kwargs has to be either None or a node that is used as node for dynamic positional (*args) or keyword (**kwargs) arguments. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Compare(*expr*, *ops*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Compare "Permalink to this definition") Compares an expression with some other expressions. ops must be a list of [Operand](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Operand "jinja2.nodes.Operand")s. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Concat(*nodes*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Concat "Permalink to this definition") Concatenates the list of expressions provided after converting them to unicode. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.CondExpr(*test*, *expr1*, *expr2*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.CondExpr "Permalink to this definition") A conditional expression (inline if expression). ({{ foo if bar else baz }}) Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.ContextReference[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.ContextReference "Permalink to this definition") Returns the current template context. It can be used like a [Name](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Name "jinja2.nodes.Name") node, with a 'load'ctx and will return the current [Context](http://docs.jinkan.org/docs/jinja2/api.html#jinja2.runtime.Context "jinja2.runtime.Context") object. Here an example that assigns the current template name to a variable named foo: ~~~ Assign(Name('foo', ctx='store'), Getattr(ContextReference(), 'name')) ~~~ Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.EnvironmentAttribute(*name*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.EnvironmentAttribute "Permalink to this definition") Loads an attribute from the environment object. This is useful for extensions that want to call a callback stored on the environment. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.ExtensionAttribute(*identifier*, *name*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.ExtensionAttribute "Permalink to this definition") Returns the attribute of an extension bound to the environment. The identifier is the identifier of the Extension. This node is usually constructed by calling the [attr()](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.ext.Extension.attr "jinja2.ext.Extension.attr") method on an extension. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Filter(*node*, *name*, *args*, *kwargs*, *dyn_args*, *dyn_kwargs*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Filter "Permalink to this definition") This node applies a filter on an expression. name is the name of the filter, the rest of the fields are the same as for [Call](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Call "jinja2.nodes.Call"). If the node of a filter is None the contents of the last buffer are filtered. Buffers are created by macros and filter blocks. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Getattr(*node*, *attr*, *ctx*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Getattr "Permalink to this definition") Get an attribute or item from an expression that is a ascii-only bytestring and prefer the attribute. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Getitem(*node*, *arg*, *ctx*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Getitem "Permalink to this definition") Get an attribute or item from an expression and prefer the item. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.ImportedName(*importname*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.ImportedName "Permalink to this definition") If created with an import name the import name is returned on node access. For example ImportedName('cgi.escape') returns the escape function from the cgi module on evaluation. Imports are optimized by the compiler so there is no need to assign them to local variables. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.InternalName(*name*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.InternalName "Permalink to this definition") An internal name in the compiler. You cannot create these nodes yourself but the parser provides a [free_identifier()](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.parser.Parser.free_identifier "jinja2.parser.Parser.free_identifier") method that creates a new identifier for you. This identifier is not available from the template and is not threated specially by the compiler. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Literal[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "Permalink to this definition") Baseclass for literals. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Const(*value*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Const "Permalink to this definition") All constant values. The parser will return this node for simple constants such as 42 or"foo" but it can be used to store more complex values such as lists too. Only constants with a safe representation (objects where eval(repr(x)) == x is true). Node type: [Literal](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "jinja2.nodes.Literal") *class *jinja2.nodes.Dict(*items*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Dict "Permalink to this definition") Any dict literal such as {1: 2, 3: 4}. The items must be a list of [Pair](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Pair "jinja2.nodes.Pair") nodes. Node type: [Literal](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "jinja2.nodes.Literal") *class *jinja2.nodes.List(*items*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.List "Permalink to this definition") Any list literal such as [1, 2, 3] Node type: [Literal](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "jinja2.nodes.Literal") *class *jinja2.nodes.TemplateData(*data*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.TemplateData "Permalink to this definition") A constant template string. Node type: [Literal](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "jinja2.nodes.Literal") *class *jinja2.nodes.Tuple(*items*, *ctx*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Tuple "Permalink to this definition") For loop unpacking and some other things like multiple arguments for subscripts. Like for [Name](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Name "jinja2.nodes.Name") ctx specifies if the tuple is used for loading the names or storing. Node type: [Literal](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Literal "jinja2.nodes.Literal") *class *jinja2.nodes.MarkSafe(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.MarkSafe "Permalink to this definition") Mark the wrapped expression as safe (wrap it as Markup). Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.MarkSafeIfAutoescape(*expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.MarkSafeIfAutoescape "Permalink to this definition") Mark the wrapped expression as safe (wrap it as Markup) but only if autoescaping is active. New in version 2.5. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Name(*name*, *ctx*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Name "Permalink to this definition") Looks up a name or stores a value in a name. The ctx of the node can be one of the following values: * store: store a value in the name * load: load that name * param: like store but if the name was defined as function parameter. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Slice(*start*, *stop*, *step*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Slice "Permalink to this definition") Represents a slice object. This must only be used as argument for Subscript. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Test(*node*, *name*, *args*, *kwargs*, *dyn_args*, *dyn_kwargs*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Test "Permalink to this definition") Applies a test on an expression. name is the name of the test, the rest of the fields are the same as for [Call](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Call "jinja2.nodes.Call"). Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.UnaryExpr(*node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.UnaryExpr "Permalink to this definition") Baseclass for all unary expressions. Node type: [Expr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Expr "jinja2.nodes.Expr") *class *jinja2.nodes.Neg(*node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Neg "Permalink to this definition") Make the expression negative. Node type: [UnaryExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.UnaryExpr "jinja2.nodes.UnaryExpr") *class *jinja2.nodes.Not(*node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Not "Permalink to this definition") Negate the expression. Node type: [UnaryExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.UnaryExpr "jinja2.nodes.UnaryExpr") *class *jinja2.nodes.Pos(*node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Pos "Permalink to this definition") Make the expression positive (noop for most expressions) Node type: [UnaryExpr](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.UnaryExpr "jinja2.nodes.UnaryExpr") *class *jinja2.nodes.Helper[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Helper "Permalink to this definition") Nodes that exist in a specific context only. Node type: [Node](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node "jinja2.nodes.Node") *class *jinja2.nodes.Keyword(*key*, *value*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Keyword "Permalink to this definition") A key, value pair for keyword arguments where key is a string. Node type: [Helper](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Helper "jinja2.nodes.Helper") *class *jinja2.nodes.Operand(*op*, *expr*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Operand "Permalink to this definition") Holds an operator and an expression. The following operators are available: %, **, *, +,-, //, /, eq, gt, gteq, in, lt, lteq, ne, not, notin Node type: [Helper](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Helper "jinja2.nodes.Helper") *class *jinja2.nodes.Pair(*key*, *value*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Pair "Permalink to this definition") A key, value pair for dicts. Node type: [Helper](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Helper "jinja2.nodes.Helper") *class *jinja2.nodes.Stmt[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "Permalink to this definition") Base node for all statements. Node type: [Node](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node "jinja2.nodes.Node") *class *jinja2.nodes.Assign(*target*, *node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Assign "Permalink to this definition") Assigns an expression to a target. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Block(*name*, *body*, *scoped*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Block "Permalink to this definition") A node that represents a block. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Break[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Break "Permalink to this definition") Break a loop. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.CallBlock(*call*, *args*, *defaults*, *body*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.CallBlock "Permalink to this definition") Like a macro without a name but a call instead. call is called with the unnamed macro as caller argument this node holds. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Continue[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Continue "Permalink to this definition") Continue a loop. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.EvalContextModifier(*options*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.EvalContextModifier "Permalink to this definition") Modifies the eval context. For each option that should be modified, a [Keyword](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Keyword "jinja2.nodes.Keyword") has to be added to the options list. Example to change the autoescape setting: ~~~ EvalContextModifier(options=[Keyword('autoescape', Const(True))]) ~~~ Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.ScopedEvalContextModifier(*options*, *body*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.ScopedEvalContextModifier "Permalink to this definition") Modifies the eval context and reverts it later. Works exactly like [EvalContextModifier](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.EvalContextModifier "jinja2.nodes.EvalContextModifier")but will only modify the [EvalContext](http://docs.jinkan.org/docs/jinja2/api.html#jinja2.nodes.EvalContext "jinja2.nodes.EvalContext") for nodes in the body. Node type: [EvalContextModifier](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.EvalContextModifier "jinja2.nodes.EvalContextModifier") *class *jinja2.nodes.ExprStmt(*node*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.ExprStmt "Permalink to this definition") A statement that evaluates an expression and discards the result. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Extends(*template*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Extends "Permalink to this definition") Represents an extends statement. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.FilterBlock(*body*, *filter*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.FilterBlock "Permalink to this definition") Node for filter sections. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.For(*target*, *iter*, *body*, *else_*, *test*, *recursive*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.For "Permalink to this definition") The for loop. target is the target for the iteration (usually a [Name](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Name "jinja2.nodes.Name") or [Tuple](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Tuple "jinja2.nodes.Tuple")), iter the iterable. body is a list of nodes that are used as loop-body, and else_ a list of nodes for the else block. If no else node exists it has to be an empty list. For filtered nodes an expression can be stored as test, otherwise None. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.FromImport(*template*, *names*, *with_context*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.FromImport "Permalink to this definition") A node that represents the from import tag. It’s important to not pass unsafe names to the name attribute. The compiler translates the attribute lookups directly into getattr calls and does *not* use the subscript callback of the interface. As exported variables may not start with double underscores (which the parser asserts) this is not a problem for regular Jinja code, but if this node is used in an extension extra care must be taken. The list of names may contain tuples if aliases are wanted. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.If(*test*, *body*, *else_*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.If "Permalink to this definition") If test is true, body is rendered, else else_. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Import(*template*, *target*, *with_context*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Import "Permalink to this definition") A node that represents the import tag. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Include(*template*, *with_context*, *ignore_missing*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Include "Permalink to this definition") A node that represents the include tag. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Macro(*name*, *args*, *defaults*, *body*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Macro "Permalink to this definition") A macro definition. name is the name of the macro, args a list of arguments anddefaults a list of defaults if there are any. body is a list of nodes for the macro body. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Output(*nodes*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Output "Permalink to this definition") A node that holds multiple expressions which are then printed out. This is used both for the print statement and the regular template data. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Scope(*body*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Scope "Permalink to this definition") An artificial scope. Node type: [Stmt](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Stmt "jinja2.nodes.Stmt") *class *jinja2.nodes.Template(*body*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Template "Permalink to this definition") Node that represents a template. This must be the outermost node that is passed to the compiler. Node type: [Node](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Node "jinja2.nodes.Node") *exception *jinja2.nodes.Impossible[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.nodes.Impossible "Permalink to this definition") Raised if the node could not perform a requested action.
';

自动转义扩展

最后更新于:2022-04-01 04:04:40

**Import name:** jinja2.ext.autoescape New in version 2.4. 自动转义扩展允许你在模板内开关自动转义特性。如果环境的 autoescape 设定为 False ,它可以被激活。如果是 True 可以被关闭。这个设定的覆盖是有作用域的。
';

With 语句

最后更新于:2022-04-01 04:04:38

**Import name:** jinja2.ext.with_ New in version 2.3. 这个扩展添加了 with 关键字支持。使用这个关键字可以在模板中强制一块嵌套的 作用域。变量可以在 with 语句的块头中直接声明,或直接在里面使用标准的 set 语句。
';

循环控制

最后更新于:2022-04-01 04:04:36

**Import name:** jinja2.ext.loopcontrols 这个扩展添加了循环中的 break 和 continue 支持。在启用它之后, Jinja2 提供的这两个关键字如同 Python 中那样工作。
';

表达式语句

最后更新于:2022-04-01 04:04:33

**Import name:** jinja2.ext.do “do”又叫做表达式语句扩展,向模板引擎添加了一个简单的 do 标签,其工作如同 一个变量表达式,只是忽略返回值。
';

i18n 扩展

最后更新于:2022-04-01 04:04:31

**Import name:** jinja2.ext.i18n Jinja2 当前只附带一个扩展,就是 i18n 扩展。它可以与 [gettext](http://docs.python.org/dev/library/gettext) 或 [babel](http://babel.edgewall.org/) 联合使用。如果启用了 i18n 扩展, Jinja2 提供了 trans 语句来标记被其包裹的 字符串为可翻译的,并调用 gettext 。 在启用虚拟的 _ 函数后,之后的 gettext 调用会被添加到环境的全局变量。那么 一个国际化的应用应该不仅在全局,以及在每次渲染中在命名空间中提供至少一个 gettext 或可选的ngettext 函数。 ### 环境方法[](http://docs.jinkan.org/docs/jinja2/extensions.html#id3 "Permalink to this headline") 在启用这个扩展后,环境提供下面的额外方法: jinja2.Environment.install_gettext_translations(*translations*, *newstyle=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.Environment.install_gettext_translations "Permalink to this definition") 在该环境中全局安装翻译。提供的翻译对象要至少实现 uggettext 和 ungettext 。gettext.NullTranslations 和 gettext.GNUTranslations 类和 [Babel](http://babel.edgewall.org/)‘s 的 Translations 类也被支持。 Changed in version 2.5: 添加了新样式的 gettext jinja2.Environment.install_null_translations(*newstyle=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.Environment.install_null_translations "Permalink to this definition") 安装虚拟的 gettext 函数。这在你想使应用为国际化做准备但还不想实现完整的 国际化系统时很有用。 Changed in version 2.5: 添加了新样式的 gettext jinja2.Environment.install_gettext_callables(*gettext*, *ngettext*,*newstyle=False*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.Environment.install_gettext_callables "Permalink to this definition") 在环境中把给出的 gettext 和 ngettext 可调用量安装为全局变量。它们 应该表现得几乎与标准库中的 gettext.ugettext() 和 gettext.ungettext() 函数相同。 如果激活了 新样式 ,可调用量被包装为新样式的可调用量一样工作。更多 信息见 [*新样式 Gettext*](http://docs.jinkan.org/docs/jinja2/extensions.html#newstyle-gettext) 。 New in version 2.5. jinja2.Environment.uninstall_gettext_translations()[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.Environment.uninstall_gettext_translations "Permalink to this definition") 再次卸载翻译。 jinja2.Environment.extract_translations(*source*)[](http://docs.jinkan.org/docs/jinja2/extensions.html#jinja2.Environment.extract_translations "Permalink to this definition") 从给定的模板或源中提取本地化字符串。 对找到的每一个字符串,这个函数生产一个 (lineno, function, message ) 元组,在这里: * lineno 是这个字符串所在行的行号。 * function 是 gettext 函数使用的名称(如果字符串是从内嵌的 Python 代码中抽取的)。 * message 是字符串本身(一个 unicode 对象,在函数有多个字符串参数 时是一个unicode 对象的元组)。 如果安装了 [Babel](http://babel.edgewall.org/) , [*Babel 集成*](http://docs.jinkan.org/docs/jinja2/integration.html#babel-integration) 可以用来为 babel 抽取字符串。 对于一个对多种语言可用而对所有用户给出同一种的语言的 web 应用(例如一个法国社 区安全了一个多种语言的论坛软件)可能会一次性加载翻译并且在环境生成时把翻译方 法添加到环境上: ~~~ translations = get_gettext_translations() env = Environment(extensions=['jinja2.ext.i18n']) env.install_gettext_translations(translations) ~~~ get_get_translations 函数会返回当前配置的翻译器。(比如使用 gettext.find ) 模板设计者的 i18n 扩展使用在 [*模板文档*](http://docs.jinkan.org/docs/jinja2/templates.html#i18n-in-templates) 中有描述。 ### 新样式 Gettext[](http://docs.jinkan.org/docs/jinja2/extensions.html#newstyle-gettext "Permalink to this headline") New in version 2.5. 从版本 2.5 开始你可以使用新样式的 gettext 调用。这些的启发源于 trac 的内部 gettext 函数并且完全被 babel 抽取工具支持。如果你不使用 Babel 的抽取工具, 它可能不会像其它抽取工具预期的那样工作。 标准 gettext 调用和新样式的 gettext 调用有什么区别?通常,它们要输入的东西 更少,出错率更低。并且如果在自动转义环境中使用它们,它们也能更好地支持自动 转义。这里是一些新老样式调用的差异: 标准 gettext: ~~~ {{ gettext('Hello World!') }} {{ gettext('Hello %(name)s!')|format(name='World') }} {{ ngettext('%(num)d apple', '%(num)d apples', apples|count)|format( num=apples|count )}} ~~~ 新样式看起来是这样: ~~~ {{ gettext('Hello World!') }} {{ gettext('Hello %(name)s!', name='World') }} {{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }} ~~~ 新样式 gettext 的优势是你需要输入的更少,并且命名占位符是强制的。后者看起 来似乎是缺陷,但解决了当翻译者不能切换两个占位符的位置时经常勉励的一大堆 麻烦。使用新样式的 gettext ,所有的格式化字符串看起来都一样。 除此之外,在新样式 gettext 中,如果没有使用占位符,字符串格式化也会被使用, 这使得所有的字符串表现一致。最后,不仅是新样式的 gettext 调用可以妥善地为 解决了许多转义相关问题的自动转义标记字符串,许多模板也在使用自动转义时体验 了多次。
';