Flask模板引擎之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开发》,很多⼈都能写出来这些,但除了书⾥讲的,你还应该了解⼀些其他的语法细节。这篇⽂章就来介绍⼀些常⽤的语法和函数,如果想要系统完整的了解Jinja,可以去读它的⽂档:。
FAQ
在Jinja⽹站上的FAQ⾥,我挑了三个⼤家可能会⽐较感兴趣的问题(简单翻译了⼀下)。
字符串函数的length属性1、为什么要叫Jinja?
之所以叫Jinja,是因为⽇本的神社(Jinja)英⽂单词是temple,⽽模板的英⽂是template,两者发⾳很相似(这么说来,它本来也有可能叫Miao的……)。
2、Jinja的速度怎么样?
和Mako差不多,但⽐Genshi以及Django的模板引擎快10~20倍。
3、把逻辑判断(Logic)放到模板⾥是个好主意吗?
毫⽆疑问,你放到模板⾥逻辑判断(Logic)应该越少越好。但为了让⼤家都开⼼,适当的逻辑判断是需要的。尽管如此,它有很多对于你能做什么,不能做什么的限制。
出于诸多考虑(速度,易读性等等),Jinja既不允许你放置任意的Python代码,也不允许所有的Python表达式。这也是为什么我们要了解Jinja2的语法。
Delimiters(分隔符)
{% ... %} 语句()
{{ ... }} 打印模板输出的表达式()
{# ... #} 注释
# ... ## ⾏语句()
多说⼀下注释,这是单⾏注释:
{#% 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(', ') }}
常⽤的内置过滤器:
safe 渲染时不转义
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 左边如果是列表,输出列表的数量;如果是字符串,则输出字符串的长度
……
Tests(测试,判断)
Jinja2提供的tests可以⽤来在语句⾥对变量或表达式进⾏测试,如果要测试⼀个变量,可以在变量后加上“is”和test名,⽐如:{% if user.age is equalto 42 %} {# 这⾥也可以写成... is equalto(42) #}
Ha, you are 42!
{% endif %}
如果要传⼊参数,可以在test后增加括号,也可以直接写在后⾯。
常⽤的test(未说明的均返回True或False):
defined
equalto
escaped
none
sequence
string
number
reverse
replace
......
完整的test列表及⽤法见:
Loop(循环)
在⼀个for循环内,有⼀些特殊的变量可以使⽤,这是⼏个常⽤的:
loop.index 当前迭代数,可以⽤来写评论的楼层数(从1开始)
loop.index0 同上,不过从0开始迭代
loop.length 序列的数量
loop.first 是否是第⼀个元素
loop.last 是否是最后⼀个元素
......
Whitespace Control(空格控制)
默认的设置:
1. 如果末尾有换⾏符,则去除;
2. 其他空格原样保留。
也就是说,下⾯这⼏⾏:
<div>
{% if True %}
yay
{% endif %}
</div>
渲染后的结果是这样:
<div>
yay
</div>
Jinja2语句占据的空⾏,你⾃⼰输出的空格,Tab都将保留。
如果要去掉Jinja2语句占据的空⾏,可以通过设置Jinja2的环境变量实现:
app.im_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>
Escaping(转义)
有时你会想原样输出⼀些Jinja2语句和分隔符,对于⼩的内容,可以使⽤变量表达式来输出,⽐如输出⼀个分隔符:
{{ '{{' }}
⼤的内容块可以使⽤⼀个raw块包裹:
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
模板继承
你可以创建⼀个base.html作为基模板,把导航栏、页脚、flash消息、js或css⽂件等等需要在每⼀个页⾯中显⽰的内容放在基模板⾥,并添加⼀个空的块⽤来放置其他⼦模板的内容:
{% block content %}{% endblock %}
然后在其他的模板(⼦模板)⾥使⽤这个extends语句继承它,并放置相应的内容到基模板⾥定义过的空块:{% extends "base.html" %}
{% block content %}
⼦模板的内容
{% endblock %}
如果想添加内容到在⽗模板内已经定义的块,可以使⽤super函数:
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ super() }}
{% endblock %}
这样可以避免覆盖⽗块的内容。
全局函数
常⽤的全局函数有:
range([start, ]stop[, step])
lipsum(n=5, html=True, min=20, max=100) 为模板⽣成⼀些 lorem ipsum。
详细列表见:
其他内容
内容还有很多,⽐如⾏语句、控制流、表达式、宏等。不再⼀⼀介绍了(写这种介绍⽂章太累了……)。
具体见⽂档的模板部分:
相关链接
Jinja主页:
Jinja2⽂档:
Jinja2⽂档模板部分:
Github项⽬页:
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论