Flask模板引擎Jinja2核心语法详解:从基础到高级应用
本文深入解析Flask内置的Jinja2模板引擎,系统介绍其核心语法。内容涵盖分隔符使用、变量与对象属性访问、内置过滤器(如safe、default、truncate)及测试函数、For循环中的特殊变量、空格控制机制、转义处理以及模板继承与宏定义。通过具体代码示例,帮助开发者掌握Jinja2在Web开发中的实际应用技巧。
Jinja2简介与常见问题
Jinja是构成Flask框架的核心模板引擎。即便你对它的具体运作机制尚不熟悉,但以下这些包含百分号和大括号的符号结构你一定并不陌生:
{% block body %}
<ul>
{% for user in users %}
<li><a href="{{ user.url }}" rel="external nofollow" >{{ user.username }}</a></li>
{% endfor %}
</ul>
{% endblock %}
阅读《Flask Web开发》的读者通常能够编写出此类代码,但除了书中提及的基础知识外,掌握更多语法细节至关重要。本文将重点介绍Jinja2中常用且实用的语法与函数。若需系统性地深入了解,建议查阅官方文档:Jinja2 Documentation。
常见问题解答(FAQ)
在Jinja官方网站的FAQ栏目中,我筛选了三个用户关注度较高的问题(此处进行了简化翻译),供读者参考。
1、为何命名为Jinja?
名称“Jinja”源自日语中“神社”一词(Jinja),其英文对应词为“temple”。而“模板”的英文是“template”,两者发音相近。有趣的是,如果按音译逻辑,它或许也可以被命名为“Miao”(庙)。
2、Jinja的执行速度如何?
其性能表现与Mako模板引擎相当,但相比Genshi以及Django自带的模板引擎,速度提升了10至20倍。
3、在模板中引入逻辑判断(Logic)是否合理?
毫无疑问,模板中的逻辑判断应尽可能精简。然而,为了兼顾开发效率与用户体验,适度的逻辑处理是必要的。尽管如此,Jinja对模板中可执行的逻辑操作设有诸多限制。
出于对执行速度、代码可读性等多方面的考量,Jinja并不允许在模板中直接放置任意Python代码或执行所有Python表达式。这正是我们需要深入理解Jinja2语法规则的原因。
基础语法:分隔符与注释
分隔符(Delimiters)
Jinja2使用特定的分隔符来界定不同类型的指令: {% ... %} 用于定义语句(Statements) {{ ... }} 用于输出表达式(Expressions)的结果 {# ... #} 用于单行或多行注释 # ... ## 用于行内语句(Line Statements)
关于注释部分,这里展示的是单行注释的写法:
{#% for user in users %#}
以下是多行注释的示例:
{# note: commented-out template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
变量访问与属性获取
变量(Variables)
除了基础的字符串变量,Jinja2同样支持列表、字典及对象类型。你可以通过以下方式获取变量的值:
{{ mydict['key'] }}
{{ mylist[3] }}
{{ mylist[myintvar] }}
{{ myobj.somemethod() }}
访问变量属性主要有两种语法:
{{ foo.bar }}
{{ foo['bar'] }}
这两种方式在大多数场景下效果基本一致(深层差异在此暂不展开讨论)。
过滤器与测试函数详解
过滤器(Filter)
过滤器用于对变量进行转换或处理,通过竖线(|)与变量名分隔。
{{ items|join(', ') }}
以下是Jinja2常用的内置过滤器列表:
- safe:渲染时不进行HTML转义
- capitalize:将字符串首字母转换为大写
- lower:将字符串转换为小写
- upper:将字符串转换为大写
- title:将字符串中每个单词的首字母转换为大写
- trim:去除字符串首尾的空格
- striptags:移除字符串中的HTML标签
- default:为未定义的变量设置默认值。用法示例如下:
{{ my_variable|default('my_variable is not defined') }}
- random(seq):从序列中随机返回一个元素
- truncate(s, length=255, killwords=False, end='...'):截取指定长度的字符串,常用于生成文章摘要
- format(value, *args, **kwargs):功能类似于Python的字符串格式化函数
- length:若左侧为列表,返回元素数量;若为字符串,返回字符长度
- ……
完整的过滤器列表请参考:http://jinja.pocoo.org/docs/dev/templates/#builtin-filters
测试(Tests)
Jinja2提供的测试功能允许在语句中对变量或表达式进行条件判断。判断变量时,需在变量后添加“is”关键字及测试名称,例如:
{% if user.age is equalto 42 %} {# 这里也可以写成... is equalto(42) #}
Ha, you are 42!
{% endif %}
若测试需要传入参数,可以在测试名后加括号,也可以直接跟在后面。
常用的测试函数(未特别说明的均返回布尔值True或False):
- defined:检查变量是否已定义
- equalto:检查变量是否等于指定值
- escaped:检查变量是否已转义
- none:检查变量是否为None
- sequence:检查变量是否为序列类型
- string:检查变量是否为字符串类型
- number:检查变量是否为数字类型
- reverse:检查变量是否可反转
- replace:检查变量是否包含可替换内容
- ......
完整的测试列表及详细用法请参阅:Template Designer Documentation
循环控制与特殊变量
循环(Loop)
在For循环内部,可以使用一些特殊的内置变量,以下是几个常用示例:
- loop.index:当前迭代次数(从1开始计数),常用于显示评论楼层号
- loop.index0:同上,但迭代计数从0开始
- loop.revindex:反向迭代次数(基数为1)
- loop.revindex0:反向迭代次数(基数为0)
- loop.length:序列的总长度
- loop.first:判断当前元素是否为第一个
- loop.last:判断当前元素是否为最后一个
- ......
完整的循环变量列表请参考:http://jinja.pocoo.org/docs/dev/templates/#for
空格控制与转义处理
空格控制(Whitespace Control)
默认配置下的处理规则:
- 若语句末尾存在换行符,则会被去除;
- 其他空格保持原样保留。
具体表现为,以下代码段:
<div>
{% if True %}
yay
{% endif %}
</div>
渲染后的结果如下所示:
<div>
yay
</div>
Jinja2语句本身占用的空行、你手动输出的空格以及Tab缩进均会被保留。
若要去除Jinja2语句占用的空行,可以通过配置Jinja2的环境变量来实现:
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
或者,可以在语句块内部手动添加减号(注意减号与%之间不能有空格):
<div>
{% if True -%}
yay
{%- endif %}
</div>
这两种方式产生的效果相同,渲染结果如下:
<div>
yay
</div>
若在语句块的前后都加上减号:
<div>
{%- if True -%}
yay
{%- endif -%}
</div>
渲染后的结果将变为:
<div>yay</div>
通过Jinja2提供的环境变量,你可以配置多种行为,例如修改分隔符(当与其他语言冲突时,可通过调整分隔符解决)。更多细节请参考:http://jinja.pocoo.org/docs/dev/api/#jinja2.Environment
转义(Escaping)
有时你需要原样输出Jinja2语句或分隔符。对于少量内容,可以使用变量表达式输出,例如输出一个左花括号分隔符:
{{ '{{' }}
对于大段内容,可以使用raw块进行包裹:
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
模板继承与全局函数
模板继承(Template Inheritance)
你可以创建一个base.html作为基础模板,将导航栏、页脚、Flash消息、JavaScript或CSS文件等需要在所有页面中共享的内容放置在基模板中,并定义一个空块以容纳子模板的内容:
{% block content %}{% endblock %}
在其他子模板中,使用extends语句继承基模板,并将具体内容填入基模板中定义的对应空块:
{% extends "base.html" %}
{% block content %}
子模板的内容
{% endblock %}
若需向父模板中已定义的块追加内容,可使用super函数:
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ super() }}
{% endblock %}
这种方式可以有效避免覆盖父模板中已定义的内容。
全局函数(Global Functions)
常用的全局函数包括:
- range([start, ]stop[, step]):生成一个数字序列
- lipsum(n=5, html=True, min=20, max=100):为模板生成Lorem Ipsum占位文本
详细的全局函数列表请参阅:Template Designer Documentation
其他内容
Jinja2的功能远不止于此,还包括行语句、控制流、表达式、宏定义等。由于篇幅限制,此处不再逐一赘述(撰写此类介绍性文章确实耗费精力……)。
具体内容请参阅文档的模板部分:
Template Designer Documentation
相关链接
Jinja官方网站:Jinja2 Documentation
Jinja2官方文档:Jinja2 Documentation
Jinja2文档模板章节:Template Designer Documentation
GitHub项目主页:pallets/jinja
以上就是本文的全部内容,希望能为你的学习提供帮助,也欢迎大家继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













