Jinja2

简介

Homepage, Documentation, 文档Python2, github

Jinja 是一个快速、富有表现力、可扩展的模板引擎。模板中的特殊占位符允许编写类似于 Python 语法的代码。然后向模板传递数据以呈现最终文档。

它包括:

Jinja 的理念是,虽然应用程序逻辑尽可能属于 Python,但它不应该通过过多地限制功能来使模板设计者的工作变得困难。

Jinja2快速上手

T0uken于 2024-08-24 02:34:37 发布

Jinja2 是一个广泛使用的 Python 模板引擎,它允许你使用模板语法生成动态的 HTML、XML、或者其他文本文件。Jinja2 是 Flask 和 FastAPI 等 Web 框架中默认的模板引擎,但它也可以在任何 Python 项目中独立使用。

部署与使用

安装

导入模块和类

创建模板环境

代码扩展:

可以在 Environment 中传递更多的配置参数,例如:

加载模板

代码扩展:

渲染模板

代码扩展:

假设我们有以下模板 my_template.html

当我们使用 template.render(user_name="Alice", user_is_admin=True) 渲染这个模板时,最终生成的 rendered_html 将是:

使用多变量渲染

除了单一变量传递外,render 方法可以接受任意数量的键值对参数:

对应的模板可能会这样写:

渲染结果会是:

模板

变量插值

Jinja2 允许在模板中使用双花括号 {{ }} 语法插入变量。变量插值是 Jinja2 最基本的功能之一,通常用于动态生成内容。

示例代码:
Python 代码:
解释:

控制结构

Jinja2 支持常见的控制结构,如条件语句 (if)、循环 (for),这使得模板能够根据条件或数据动态生成不同的内容。

循环语句示例代码:
Python 代码:
解释:

过滤器

Jinja2 提供了一系列内置过滤器,用于在模板中对变量进行格式化和处理。过滤器使用管道符号 | 进行应用,类似于 Unix 的管道操作。

常见过滤器示例:
示例代码:
Python 代码:
解释:

模板继承

模板继承是 Jinja2 的一大特色,它允许你定义一个基础模板,并在其他模板中继承和扩展该基础模板。这有助于保持代码的可维护性和一致性,尤其是在处理大型项目时。

基础模板示例代码 (base.html):
子模板示例代码 (home.html):
Python 代码:
解释:

宏(Macros)

宏类似于 Python 中的函数,用于封装可重用的模板代码。使用宏可以避免重复代码,并简化复杂的模板逻辑。

宏定义与使用示例代码:
Python 代码:
解释:

*FastAPI动态页面

在 FastAPI 中使用 Jinja2 渲染和返回动态页面是一种常见的做法,尤其是在需要生成动态 HTML 内容时。以下是详细步骤和代码示例,展示如何在 FastAPI 中集成 Jinja2 并返回动态页面。

安装依赖

首先,确保安装了 FastAPI 和 Jinja2 相关的依赖包:

项目结构

假设你的项目结构如下:

创建 FastAPI 应用并配置 Jinja2

app.py 中设置 FastAPI 应用程序并配置 Jinja2 进行模板渲染:

创建模板文件

templates 目录下创建 index.html 文件:

启动 FastAPI 应用

在终端中启动 Uvicorn 服务器以运行 FastAPI 应用:

然后访问 http://127.0.0.1:8000/,你将看到渲染后的 HTML 页面。

模板设计器文档

Google Translate from: https://jinja.palletsprojects.com/en/stable/templates/

本文档描述了模板引擎的语法和语义,对于创建 Jinja 模板的人来说非常有用。由于模板引擎非常灵活,因此应用程序中的配置在分隔符和未定义值的行为方面可能与此处提供的代码略有不同。

摘要

Jinja 模板只是一个文本文件。Jinja 可以生成任何基于文本的格式(HTML、XML、CSV、LaTeX 等)。Jinja 模板不需要有特定的扩展名:.html.xml或任何其他扩展名都可以。

模板包含变量和/或表达式,在模板呈现时它们会被替换为值;以及标签,用于控制模板的逻辑。模板语法深受 Django 和 Python 的启发。

下面是一个最小模板,它说明了使用默认 Jinja 配置的一些基本知识。我们将在本文档的后面部分介绍详细信息:

以下示例显示了默认配置设置。应用程序开发人员可以将语法配置从更改为或类似内容。{% foo %}``<% foo %>

分隔符有几种。默认的 Jinja 分隔符配置如下:

行语句和注释也是可能的,但它们没有默认前缀字符。要使用它们,请 在创建时 line_statement_prefix和。line_comment_prefixEnvironment

模板文件扩展名

如上所述,任何文件都可以作为模板加载,无论文件扩展名是什么。添加.jinja扩展名(例如)user.html.jinja 可能会使某些 IDE 或编辑器插件更容易使用,但这不是必需的。稍后介绍的自动转义可以根据文件扩展名应用,因此在这种情况下您需要考虑额外的后缀。

识别模板的另一个好方法是,它们位于 templates文件夹中,无论扩展名是什么。这是项目的常见布局。

 

变量

模板变量由传递给模板的上下文字典定义。

只要模板中的变量是由应用程序传入的,您就可以随意使用它们。变量可能具有您也可以访问的属性或元素。变量具有哪些属性在很大程度上取决于提供该变量的应用程序。

除了标准 Python “下标”语法( )之外,还可以使用点(.)来访问变量的属性。__getitem__``[]

以下几行做同样的事情:

重要的是要知道,外部双花括号不是变量的一部分,而是打印语句的一部分。如果您访问标签内的变量,请不要将括号括起来。

如果变量或属性不存在,您将返回未定义的值。您可以对这种值执行的操作取决于应用程序配置:默认行为是,如果打印或迭代,则计算结果为空字符串,而对于其他所有操作,则计算结果为失败。

执行

为了方便起见,foo.barJinja 在 Python 层做了以下事情:

foo['bar']工作原理基本相同,只是顺序略有不同:

如果对象有同名的项目和属性,这一点很重要。此外,attr()过滤器仅查找属性。

 

过滤器

变量可以通过过滤器进行修改。过滤器与变量之间用竖线符号 ( ) 分隔|,并且可以在括号中带有可选参数。可以串联多个过滤器。一个过滤器的输出将应用于下一个过滤器。

例如,将从变量中删除所有 HTML 标签并将输出改为标题大小写()。{{ name|striptags|title }}``name``title(striptags(name))

接受参数的过滤器在参数周围有括号,就像函数调用一样。例如:将使用逗号 ( ) 连接列表。{{ listx|join(', ') }}``str.join(', ', listx)

下面的内置过滤器列表描述了所有内置过滤器。

 

测试

除了过滤器之外,还有所谓的“测试”可用。测试可用于根据常见表达式测试变量。要测试变量或表达式,请is在变量后添加测试名称。例如,要确定变量是否已定义,您可以执行,然后它将根据当前模板上下文中是否已定义返回 true 或 false。name is defined``name

测试也可以接受参数。如果测试只接受一个参数,则可以省略括号。例如,以下两个表达式执行相同的操作:

下面的内置测试列表描述了所有内置测试。

 

评论

要注释掉模板中某一行的某部分,请使用注释语法,该语法默认设置为。这对于注释掉模板的某些部分以进行调试或为其他模板设计者或您自己添加信息非常有用:{# ... #}

空格控制

在默认配置中:

如果应用程序将 Jinja 配置为trim_blocks,则会自动删除模板标记后的第一个换行符(就像在 PHP 中一样)。lstrip_blocks 还可以将选项设置为从行首到块开头删除制表符和空格。 (如果块开头之前有其他字符,则不会删除任何内容。)

当同时禁用trim_blockslstrip_blocks时(默认),块标签所在的行将被删除,但会保留一个空白行,并且内容中的空格将被保留。例如,此模板:

当和都trim_blocks禁用时lstrip_blocks,模板将在 div 内呈现空行:

trim_blocks和都lstrip_blocks启用时,模板块行将被完全删除:

您可以通过在块开头lstrip_blocks放置加号 ( ) 来手动禁用该行为:+

类似地,您可以通过在块末尾trim_blocks放置加号()来手动禁用该行为:+

您还可以手动去除模板中的空格。如果您-在块(例如For标签)、注释或变量表达式的开头或结尾添加减号 ( ),则该块之前或之后的空格将被删除:

这将输出所有元素之间没有空格。如果是从到的seq数字列表,则输出为。1``9``123456789

如果启用了行语句,它们会自动删除行首之前的空格。

默认情况下,Jinja 还会删除尾随换行符。要保留单个尾随换行符,请将 Jinja 配置为keep_trailing_newline

笔记

标签和减号之间不能添加空格。

有效的

无效的

转义

有时,让 Jinja 忽略它本来会作为变量或块处理的部分是可取的(甚至是必要的)。例如,如果使用默认语法,您想{{在模板中将其用作原始字符串而不是启动变量,则必须使用技巧。

输出文字变量分隔符({{)的最简单方法是使用变量表达式:

对于较大的部分,标记一个块是有意义的raw。例如,要在模板中包含示例 Jinja 语法,您可以使用此代码片段:

笔记

标签末尾的减号会清除原始数据第一个字符之前的所有空格和换行符。{% raw -%}

 

行语句

如果应用程序启用了行语句,则可以将行标记为语句。例如,如果将行语句前缀配置为#,则以下两个示例是等效的:

行语句前缀可以出现在行中的任何位置,只要它前面没有文本即可。为了提高可读性,以块开头的语句(例如 for、等)可以以冒号结尾:if``elif

笔记

如果有左括号、大括号或方括号,行语句可以跨越多行:

从 Jinja 2.2 开始,基于行的注释也可用。例如,如果将行注释前缀配置为##,则从##行到行尾的所有内容都将被忽略(换行符除外):

 

模板继承

Jinja 最强大的部分是模板继承。模板继承允许您构建一个基本“骨架”模板,其中包含站点的所有常见元素,并定义子模板可以覆盖的块。

听起来很复杂,但其实很简单。从一个例子开始最容易理解。

基础模板

这个模板,我们称之为base.html,定义了一个简单的 HTML 骨架文档,您可以将其用于简单的两列页面。“子”模板的工作是用内容填充空白块:

在这个例子中,标签定义了子模板可以填充的四个块。标签所做的就是告诉模板引擎子模板可能会覆盖模板中的那些占位符。{% block %}``block

block标签可以位于其他块内,例如if,但无论if块是否实际呈现,它们都会始终被执行。

子模板

子模板可能如下所示:

标签是这里的关键。它告诉模板引擎此模板“扩展”了另一个模板。当模板系统评估此模板时,它首先定位父级。extends 标签应该是模板中的第一个标签。它之前的所有内容都会正常打印出来,可能会引起混淆。有关此行为以及如何利用它的详细信息,请参阅Null-Default Fallback。此外,无论周围条件的评估结果为真还是假,块都会始终被填充。{% extends %}

模板的文件名取决于模板加载器。例如, FileSystemLoader允许您通过提供文件名来访问其他模板。您可以使用斜杠访问子目录中的模板:

但此行为可能取决于嵌入 Jinja 的应用程序。请注意,由于子模板未定义footer块,因此将使用父模板中的值。

您不能在同一个模板中定义多个同名的标签。存在此限制是因为块标签在“两个”方向上都起作用。也就是说,块标签不仅提供要填充的占位符 - 它还定义填充父级中占位符的内容。如果模板中有两个名称相似的标签,则该模板的父级将不知道要使用哪个块的内容。{% block %}``{% block %}

但是,如果您想多次打印一个块,则可以使用特殊 self变量并调用具有该名称的块:

超级块

可以通过调用 来渲染父块的内容super()。这将返回父块的结果:

嵌套扩展

在有多个级别的情况下, 可以通过链接引用(如)来跳过继承树中的级别。{% extends %}``super``super.super()

例如:

渲染child.tmpl将给出 body: Hi from child. Hi from parent.

渲染grandchild1.tmpl将给出 body: Hi from grandchild1.

渲染grandchild2.tmpl将给出 body: Hi from grandchild2. Hi from parent.

命名块结束标签

Jinja 允许您将块的名称放在结束标记之后,以提高可读性:

但是单词后面的名称endblock必须与块名称相匹配。

块嵌套和范围

块可以嵌套以实现更复杂的布局。默认情况下,块不能访问块外部的变量(外部作用域):

此示例将输出空<li>项,因为item块内不可用。原因是如果块被子模板替换,则会出现一个未在块中定义或未传递给上下文的变量。

scoped 从 Jinja 2.2 开始,您可以通过在块声明中添加修饰符将块设置为“作用域”,从而明确指定块中的变量可用:

覆盖块时,scoped不必提供修饰符。

必需块

块可以标记为required。它们必须在某个时候被覆盖,但不一定由直接子模板覆盖。必需的块可能只包含空格和注释,并且不能直接呈现。

渲染page.txtissue.txt将引发 TemplateRuntimeError,因为它们不会覆盖body块。渲染bug_report.txt将成功,因为它会覆盖块。

与 结合使用时scopedrequired修饰符必须放在 作用域修饰符之后。以下是一些有效示例:

模板对象

extendsincludeimport可以采用模板对象而不是要加载的模板名称。这在某些高级情况下可能很有用,因为您可以使用 Python 代码先加载模板并将其传递给render

注意如何extends将变量与传递给的模板对象一起传递render,而不是字符串。

HTML 转义

从模板生成 HTML 时,变量中包含的字符可能会影响生成的 HTML,这种风险始终存在。有两种方法:

  1. 手动转义每个变量;或者
  2. 默认情况下自动转义所有内容。

Jinja 支持这两种方式。具体使用哪种方式取决于应用程序配置。默认配置是没有自动转义的;原因如下:

使用手动转义

如果启用了手动转义,则有责任在需要时转义变量。要转义什么?如果您的变量可能 包含以下任何字符(><&"),则除非变量包含格式正确且受信任的 HTML,否则您 应该对其进行转义。转义通过将变量通过|e过滤器进行管道传输来实现:

使用自动转义

启用自动转义后,除了明确标记为安全的值之外,所有内容都会默认转义。变量和表达式可以在以下任一情况下标记为安全:

  1. 应用程序的上下文词典 markupsafe.Markup
  2. 模板,带有|safe过滤器。

如果您标记为安全的字符串通过无法理解该标记的其他 Python 代码传递,则可能会丢失。请注意您的数据何时被标记为安全以及在到达模板之前如何处理它。

如果某个值已转义但未标记为安全,则仍将进行自动转义并导致出现双转义字符。如果您知道您有已经安全但未标记的数据,请务必将其包装起来 Markup或使用|safe过滤器。

Jinja 函数(宏super、、self.BLOCKNAME)始终返回标记为安全的模板数据。

具有自动转义的模板中的字符串文字被认为是不安全的,因为原生 Python 字符串并不安全。

 

控制结构列表

控制结构是指控制程序流程的所有内容 - 条件(即 if/elif/else)、for 循环以及宏和块之类的内容。使用默认语法,控制结构出现在 块内。{% ... %}

 

为了

循环遍历序列中的每个项目。例如,要显示名为的变量中提供的用户列表users

由于模板中的变量保留其对象属性,因此可以对容器进行迭代,例如dict

Python 字典的显示顺序可能不符合您的要求。如果顺序很重要,请使用|dictsort过滤器。

在 for 循环块中,你可以访问一些特殊变量:

多变的描述
loop.index循环的当前迭代。(1 个索引)
loop.index0循环的当前迭代。(0 索引)
loop.revindex从循环末尾开始的迭代次数(1 索引)
loop.revindex0从循环末尾开始的迭代次数(0 索引)
loop.first如果是第一次迭代则为真。
loop.last如果是最后一次迭代则为真。
loop.length序列中的项目数。
loop.cycle用于在序列列表之间循环的辅助函数。请参阅下面的说明。
loop.depth指示渲染当前处于递归循环的深度。从第 1 级开始
loop.depth0指示渲染当前处于递归循环的深度。从 0 级开始
loop.previtem循环中上一次迭代的项目。第一次迭代期间未定义。
loop.nextitem循环中下一次迭代的项目。上次迭代期间未定义。
loop.changed(*val)如果之前使用不同的值调用(或根本没有调用),则为 True。

在 for 循环中,可以使用特殊loop.cycle帮助器在每次循环中循环字符串/变量列表:

从 Jinja 2.1 开始,cycle有一个额外的辅助函数允许进行不受循环约束的循环。有关更多信息,请查看全局函数列表

与 Python 不同,无法在循环中使用breakcontinue。但是,您可以在迭代过程中过滤序列,这样您就可以跳过项目。以下示例跳过所有隐藏的用户:

优点是特殊loop变量将正确计数;因此不计算未迭代的用户。

如果由于序列为空或过滤从序列中删除了所有项目而没有进行迭代,则可以使用以下命令呈现默认块else

请注意,在 Python 中,else只要相应的循环未执行, break就会执行块。由于 Jinja 循环无论如何都无法执行,因此选择了break略有不同的关键字行为。else

也可以使用递归循环。如果您要处理站点地图或 RDFa 等递归数据,这很有用。要使用递归循环,您基本上必须recursive在循环定义中添加修饰符,并loop在要递归的位置使用新的可迭代对象调用变量。

以下示例实现了具有递归循环的站点地图:

loop变量始终引用最近(最内层)的循环。如果我们有多个循环级别,我们可以loop通过在要递归使用的循环后写入来重新绑定变量。然后,我们可以使用{% set outer_loop = loop %}``{{ outer_loop(...) }}

请注意,循环中的赋值将在迭代结束时被清除,并且不能超过循环范围。旧版本的 Jinja 有一个错误,在某些情况下,赋值似乎可以工作。这不受支持。有关如何处理此问题的更多信息,请参阅赋值。

如果您想要做的只是检查某个值自上次迭代以来是否发生了变化或者是否会在下一次迭代中发生变化,则可以使用previtem and nextitem

如果你只关心值是否发生了变化,使用起来changed就更简单了:

 

如果

Jinja 中的语句if与 Python 的 if 语句类似。在最简单的形式中,你可以使用它来测试变量是否已定义、不为空且不为 false:

对于多个分支,elif可以else像在 Python 中一样使用。您也可以在那里使用更复杂的表达式

如果也可以用作内联表达式和用于 循环过滤

 

宏相当于常规编程语言中的函数。宏有助于将常用的习语放入可重用的函数中,从而避免重复(“DRY”)。

下面是一个呈现表单元素的宏的小示例:

然后可以像命名空间中的函数一样调用该宏:

如果宏是在不同的模板中定义的,则必须 先导入它。

在宏内部,您可以访问三个特殊变量:

宏还会公开一些内部细节。宏对象具有以下属性:

如果宏名以下划线开头,则不会导出也无法导入。

由于 Jinja 中作用域的工作方式,子模板中的宏不会覆盖父模板中的宏。下面将输出“LAYOUT”,而不是“CHILD”。

 

称呼

在某些情况下,将一个宏传递给另一个宏会很有用。为此,您可以使用特殊call块。以下示例显示了一个利用调用功能的宏及其使用方法:

还可以将参数传回调用块。这使得它可作为循环的替代品。一般来说,调用块的工作方式与没有名称的宏完全相同。

下面是如何使用带参数的调用块的示例:

过滤器

过滤器部分允许您在模板数据块上应用常规 Jinja 过滤器。只需将代码包装在特殊filter部分中:

接受参数的过滤器可以像这样调用:

 

分配

在代码块内,您还可以为变量赋值。顶层(块、宏或循环之外)的赋值会像顶层宏一样从模板中导出,并可由其他模板导入。

作业使用set标签并且可以有多个目标:

作用域行为

请记住,不可能在块内设置变量并让它们显示在块外。这也适用于循环。该规则的唯一例外是未引入范围的 if 语句。因此,以下模板不会执行您可能期望的操作:

使用 Jinja 语法无法做到这一点。相反,可以使用替代结构,例如循环 else 块或特殊loop 变量:

从 2.10 版开始,可以使用允许跨范围传播更改的命名空间对象来处理更复杂的用例:

请注意,标签obj.attr中的符号set仅允许用于命名空间对象;尝试在任何其他对象上分配属性都会引发异常。

变更日志

块分配

可以将其用作set块,将块的内容分配给变量。这可用于创建多行字符串,因为 Jinja 不支持 Python 的三重引号 ( """, ''')。

您不需要使用等号和值,而只需写下变量名称以及捕获之前的所有内容。{% endset %}

应用于变量名称的过滤器将应用于块的内容。

变更日志

 

扩展

标记extends可用于将一个模板扩展为另一个模板。extends一个文件中可以有多个标记,但一次只能执行其中一个。

请参阅上面有关模板继承的部分。

 

块用于继承,同时充当占位符和替换。它们在 模板继承部分有详细说明。

包括

include标签渲染另一个模板并将结果输出到当前模板中。

默认情况下,包含的模板可以访问当前模板的上下文。使用来改用单独的上下文。 也是有效的,但是是默认行为。请参阅 导入上下文行为without context``with context

被包含的模板可以extend覆盖另一个模板中的块。但是,当前模板不能覆盖被包含的模板输出的任何块。

如果模板不存在,则用于忽略该语句。它必须放在上下文可见性语句之前。ignore missing

如果给出了模板列表,则将按顺序尝试每个模板,直到有一个模板不存在。这可以与忽略一起使用,如果模板不存在。ignore missing

还可以将具有模板名称或模板对象的变量传递给语句。

 

进口

Jinja 支持将常用代码放入宏中。这些宏可以进入不同的模板并从那里导入。这与 Python 中的 import 语句类似。重要的是要知道导入会被缓存,并且导入的模板默认无法访问当前模板变量,只能访问全局变量。有关导入和包含的上下文行为的更多详细信息,请参阅导入上下文行为

导入模板有两种方式。您可以将完整模板导入变量,也可以从中请求特定的宏/导出变量。

假设我们有一个渲染表单的辅助模块(称为forms.html):

访问模板变量和宏的最简单、最灵活的方法是将整个模板模块导入到变量中。这样,您就可以访问属性:

或者,您可以将模板中的特定名称导入到当前命名空间:

以一个或多个下划线开头的宏和变量是私有的,不能被导入。

变更日志

 

导入上下文行为

默认情况下,包含的模板会传递当前上下文,而导入的模板则不会。原因是导入与包含不同,会被缓存;因为导入通常仅用作包含宏的模块。

可以明确改变此行为:通过向 import/include 指令添加 或,当前上下文可以传递给模板并自动禁用缓存。with context``without context

以下有两个示例:

笔记

在 Jinja 2.0 中,传递给包含模板的上下文不包含模板中定义的变量。事实上,这是行不通的:

所 包含的模板在 Jinja 2.0 中render_box.html无法访问box。从 Jinja 2.1 开始,render_box.html 可以访问。

 

表达式

Jinja 允许在任何地方使用基本表达式。这些表达式的工作方式与常规 Python 非常相似;即使您不使用 Python,也应该能够熟练使用。

文字

最简单的表达式形式是文字。文字是 Python 对象(例如字符串和数字)的表示。存在以下文字:

笔记

特殊常量truefalsenone确实是小写的。因为这在过去会造成混淆(True用于扩展为未定义的变量,该变量被认为是错误的),所以现在这三个也可以用标题大小写(TrueFalseNone)来书写。但是,为了保持一致性(所有 Jinja 标识符都是小写的),您应该使用小写版本。

数学

Jinja 允许您使用值进行计算。这在模板中很少有用,但是为了完整性而存在的。支持以下运算符:

比较

逻辑

对于if语句、for过滤和if表达式,组合多个表达式会很有用。

其他操作符

下列运算符非常有用,但不属于其他两类:

 

If 表达式

也可以使用内联if表达式。在某些情况下,内联表达式很有用。例如,如果定义了变量,则可以使用它从一个模板扩展,否则从默认布局模板扩展:

一般语法是。<do something> if <something is true> else <do something else>

else部分是可选的。如果未提供,则 else 块会隐式评估为一个Undefined对象(无论undefined 环境中设置为何):

 

Python 方法

您还可以使用变量类型上定义的任何方法。方法调用返回的值用作表达式的值。下面是一个使用字符串上定义的方法的示例(其中page.title是字符串):

这适用于用户定义类型的方法。例如,如果 f类型的变量上定义Foo了一个方法bar,则可以执行以下操作:

操作符方法也按预期工作。例如,%为字符串实现 printf 样式:

尽管您应该更喜欢.format这种情况的方法(在呈现模板的上下文中有点不自然):

 

内置过滤器列表

abs()forceescape()map()select()unique()
attr()format()max()selectattr()upper()
batch()groupby()min()slice()urlencode()
capitalize()indent()pprint()sort()urlize()
center()int()random()string()wordcount()
default()items()reject()striptags()wordwrap()
dictsort()join()rejectattr()sum()xmlattr()
escape()last()replace()title() 
filesizeformat()length()reverse()tojson() 
first()list()round()trim() 
float()lower()safe()truncate() 

 

内置测试列表

boolean()even()in()mapping()sequence()
callable()false()integer()ne()string()
defined()filter()iterable()none()test()
divisibleby()float()le()number()true()
eq()ge()lower()odd()undefined()
escaped()gt()lt()sameas()upper()

 

全局函数列表

默认情况下,以下函数在全局范围内可用:

扩展

以下部分涵盖了应用程序可能启用的内置 Jinja 扩展。应用程序还可以提供本文档未涵盖的进一步扩展;在这种情况下,应该有单独的文档来解释所述扩展

 

国际化

如果启用了i18n 扩展,则可以将模板中的文本标记为可翻译。要将某个部分标记为可翻译,请使用以下 trans块:

块内部不允许有语句,只能有文本和简单的变量标签。

变量标签只能是名称,不能是属性访问、过滤器或其他表达式。要使用表达式,请将其绑定到 trans标签中的名称,以便在块中使用。

要绑定多个表达式,请用逗号 ( ,) 分隔每个表达式。

要使用复数形式,请指定标签分隔的单数和复数形式pluralize

默认情况下,块中的第一个变量用于确定使用单数还是复数形式。如果不正确,请将用于复数的变量指定为 的参数pluralize

翻译文本块时,空格和换行符会导致翻译字符串难以阅读且容易出错。为了避免这种情况,可以将翻译块标记为已修剪,这将用单个空格替换所有换行符及其周围的空格,并删除前导和尾随空格。

这会产生翻译文件。This is %(book_title)s. You should read it!

如果全局启用了修剪,notrimmed则可以使用修改器为某个块禁用修剪。

变更日志

如果翻译取决于消息出现的上下文,则pgettextnpgettext函数将context字符串作为第一个参数,用于选择适当的翻译。要使用标签指定上下文,请在后面提供字符串作为第一个标记。{% trans %}``trans

在 3.1 版中添加:可以将上下文传递给trans标签以使用pgettextnpgettext

可以使用以下函数翻译表达式中的字符串:

您可以像这样打印翻译的字符串:

要使用占位符,请使用format过滤器。

始终使用关键字参数format,因为其他语言可能不按相同顺序使用单词。

如果激活了新样式 Gettext调用,则使用占位符会更容易。格式化是调用的一部分,gettext而不是使用 format过滤器。

该函数的格式字符串除了给定的参数外,ngettext还会自动接收计数作为参数。num

表达式语句

如果加载了表达式语句扩展,do则可以使用名为 的标签,其工作方式与正则变量表达式 ( ) 完全相同;只是它不会打印任何内容。这可用于修改列表:{{ ... }}

循环控制

如果应用程序启用了循环控制,则可以在循环中使用break和。当达到时,循环终止;如果达到,则停止处理并继续下一次迭代。continue``break``continue

这是一个跳过每个第二项的循环:

同样,第 10 次迭代后停止处理的循环:

注意loop.index从 1 开始,并且loop.index0从 0 开始(参见:对于)。

调试语句

如果启用了调试扩展,则可以使用标签来转储当前上下文以及可用的过滤器和测试。这对于查看模板中可用的内容(无需设置调试器)非常有用。{% debug %}

With 语句

变更日志

with 语句可以创建一个新的内部作用域。在此作用域内设置的变量在作用域外不可见。

简而言之:

因为在作用域的开头设置变量很常见,所以你可以在with语句中执行此操作。以下两个示例是等效的:

这里有一个关于作用域的重要说明。在 Jinja 2.9 之前的版本中,将一个变量引用到另一个变量的行为会产生一些意想不到的后果。特别是,一个变量可以引用在同一个 with 块的开头语句中定义的另一个变量。这导致了清理后的作用域行为出现问题,此后已得到改进。特别是在较新的 Jinja 版本中,以下代码始终 a从块外部引用变量with

在早期的 Jinja 版本中,该b属性将引用第一个属性的结果。如果您依赖此行为,则可以重写它以使用set标签:

扩大

在旧版本的 Jinja(2.9 之前)中,需要使用扩展来启用此功能。现在默认启用此功能。

 

自动转义覆盖

变更日志

如果您愿意,您可以在模板内部激活或停用自动转义功能。

例子:

之后,endautoescape行为就会恢复到之前的状态。

扩大

在旧版本的 Jinja(2.9 之前)中,需要使用扩展来启用此功能。现在默认启用此功能。