📘 Jinja2 完整语法文档
以下是完整详尽的 Jinja2 语法文档,涵盖了 Jinja2 模板语言的所有核心特性与高级用法,适合用作参考手册或学习材料:
1. 基本语法与表达方式
1.1 输出变量 {{ ... }}
{{ variable_name }}
{{ user.name }}
{{ data['key'] }}
{{ list[0] }}
{{ function_call(arg1, arg2) }}
- 支持访问对象属性、字典键、列表索引。
- 支持函数调用(需在上下文中注册)。
- 输出结果会被 HTML 自动转义,除非使用
|safe
。
1.2 注释 {# ... #}
{# 这是注释,不会出现在输出中 #}
- 支持多行注释。
- 不支持嵌套注释。
1.3 控制结构 {% ... %}
{% if condition %}
...
{% endif %}
{% for item in list %}
...
{% endfor %}
- 控制结构包括:分支、循环、宏定义、模板继承等。
- 块结构必须显式关闭(如
{% endif %}
、{% endfor %}
)。
2. 控制结构详解
2.1 条件判断:if / elif / else
{% if score >= 90 %}
优秀
{% elif score >= 60 %}
合格
{% else %}
不合格
{% endif %}
- 支持逻辑运算符:
and
、or
、not
。 - 支持比较运算符:
==
、!=
、>
、<
、>=
、<=
。
2.2 for
循环
{% for user in users %}
{{ loop.index }}: {{ user.name }}
{% endfor %}
循环变量:
名称 | 含义 |
---|---|
loop.index |
从 1 开始的当前索引 |
loop.index0 |
从 0 开始的当前索引 |
loop.revindex |
从 1 开始的反向索引(总数 - 当前索引 + 1) |
loop.revindex0 |
从 0 开始的反向索引 |
loop.first |
是否是第一个元素(布尔值) |
loop.last |
是否是最后一个元素(布尔值) |
loop.length |
序列长度 |
loop.cycle(...) |
用于在循环中交替输出值 |
2.3 行内表达式(三元运算)
{{ "成人" if age >= 18 else "未成年" }}
- 类似 Python 的三元表达式:
value_if_true if condition else value_if_false
3. 过滤器与测试
3.1 常用内置过滤器
{{ text|lower }}
{{ text|upper }}
{{ text|capitalize }}
{{ text|replace("old", "new") }}
{{ number|round(2) }}
{{ html|safe }}
{{ list|length }}
{{ list|join(", ") }}
{{ string|default("N/A") }}
过滤器名 | 功能描述 |
---|---|
lower |
转为小写 |
upper |
转为大写 |
capitalize |
首字母大写,其余小写 |
replace |
替换子字符串 |
round |
四舍五入 |
safe |
标记为安全字符串(不转义 HTML) |
length |
计算长度 |
join |
用指定分隔符连接序列元素 |
default |
设置默认值 |
3.2 链式过滤器
{{ name|lower|replace("a", "@")|capitalize }}
- 过滤器可任意链式组合使用,依序处理前一个结果。
3.3 测试表达式
{% if value is defined %}
{% if num is divisibleby 5 %}
{% if name is string %}
测试器名 | 用法示例 | 描述 |
---|---|---|
defined |
value is defined |
是否已定义 |
none |
value is none |
是否为 None |
even / odd |
n is even / n is odd |
是否偶数/奇数 |
number |
value is number |
是否为数值类型 |
string |
value is string |
是否为字符串 |
divisibleby(n) |
num is divisibleby 3 |
是否能被 n 整除 |
iterable |
value is iterable |
是否可迭代对象 |
4. 宏(Macro)与调用
4.1 宏定义与参数
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
- 参数支持默认值,类似 Python 函数。
- 宏可以放在单独模板文件中导入。
4.2 宏调用
{{ input('username') }}
{{ input('age', type='number') }}
4.3 宏作用域说明
- 宏内部变量与模板外部变量隔离。
- 可通过
caller()
传递块内容(高级特性)。
5. 模板继承与 super()
5.1 模板继承基本语法
base.html:
<!DOCTYPE html>
<html>
<head><title>{% block title %}默认标题{% endblock %}</title></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
child.html:
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<p>Hello, Jinja2!</p>
{% endblock %}
5.2 使用 super()
调用父模板块内容
{% block content %}
{{ super() }}
<p>追加内容</p>
{% endblock %}
5.3 多级继承与扩展机制
- 支持多层模板继承。
- 子模板可选择性覆盖某些
block
。 - 若未覆盖,默认使用父模板中的
block
。
6. 模板加载与渲染机制
6.1 模板加载器
from jinja2 import Environment, FileSystemLoader, PackageLoader
env = Environment(loader=FileSystemLoader("templates"))
template = env.get_template("index.html")
output = template.render(name="Alice")
- FileSystemLoader:从本地文件系统加载模板。
- PackageLoader:从 Python 包中加载模板。
6.2 空白控制(Whitespace Control)
{% if condition -%}
内容
{%- endif %}
{%-
或-%}
表示去除该语句块前/后的空白符。- 有效减少 HTML 缩进、换行造成的冗余。
6.3 自动转义与安全机制
- 默认自动对
{{ }}
输出进行 HTML 转义。 - 可使用
|safe
显式声明某值为安全 HTML。 - 使用
autoescape=True
强制全局转义:
Environment(autoescape=True)
7. 可选扩展与高级特性
7.1 自定义过滤器
def reverse_string(value):
return value[::-1]
env.filters['reverse'] = reverse_string
模板中调用:
{{ "abcd"|reverse }}
7.2 自定义测试
def is_uppercase(value):
return str(value).isupper()
env.tests['uppercase'] = is_uppercase
{% if name is uppercase %}
7.3 自定义全局函数
def greet(name):
return f"Hello, {name}!"
env.globals['greet'] = greet
{{ greet("Alice") }}
7.4 模板编译机制
env.compile_templates('out_dir', zip=None, py_compile=True)
- 可将模板预编译为
.py
文件,加快加载速度。 py_compile=True
会编译为.pyc
。
7.5 调试技巧
启用调试模式:
Environment(enable_async=False)
。模板错误会显示堆栈信息(在 Flask、Django 中也可整合)。
模板语法错误通常包含以下信息:
- 行号、错误语句
- 缺失
endif
、未关闭的块等
✅ 总结
Jinja2 是功能强大、语法清晰的模板引擎,支持模板继承、宏定义、自定义扩展、安全渲染等丰富特性。熟练掌握本文档中列出的语法结构与应用方式,可以灵活构建复杂的模板系统。
扩展阅读
https://docs.jinkan.org/docs/jinja2/api.html
https://docs.jinkan.org/docs/jinja2/sandbox.html