Flask模板引擎之Jinja2语法介绍
Jinja是组成Flask的模板引擎。可能你还不太了解它是干嘛的,但你对下面这些百分号和大括号肯定不陌生:
{%blockbody%}
-
{%foruserinusers%}
{{user.username}}
{%endfor%}
看过《FlaskWeb开发》,很多人都能写出来这些,但除了书里讲的,你还应该了解一些其他的语法细节。这篇文章就来介绍一些常用的语法和函数,如果想要系统完整的了解Jinja,可以去读它的文档:Jinja2Documentation。
FAQ
在Jinja网站上的FAQ里,我挑了三个大家可能会比较感兴趣的问题(简单翻译了一下)。
1、为什么要叫Jinja?
之所以叫Jinja,是因为日本的神社(Jinja)英文单词是temple,而模板的英文是template,两者发音很相似(这么说来,它本来也有可能叫Miao的……)。
2、Jinja的速度怎么样?
和Mako差不多,但比Genshi以及Django的模板引擎快10~20倍。
3、把逻辑判断(Logic)放到模板里是个好主意吗?
毫无疑问,你放到模板里逻辑判断(Logic)应该越少越好。但为了让大家都开心,适当的逻辑判断是需要的。尽管如此,它有很多对于你能做什么,不能做什么的限制。
出于诸多考虑(速度,易读性等等),Jinja既不允许你放置任意的Python代码,也不允许所有的Python表达式。这也是为什么我们要了解Jinja2的语法。
Delimiters(分隔符)
{%...%}语句(Statements)
{{...}}打印模板输出的表达式(Expressions)
{#...#}注释
#...##行语句(LineStatements)
多说一下注释,这是单行注释:
{#%foruserinusers%#}
下面是多行注释:
{#note:commented-outtemplatebecausewenolongerusethis {%foruserinusers%} ... {%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_variableisnotdefined')}}
- random(seq)返回一个序列里的随机元素
- truncate(s,length=255,killwords=False,end='...')截取出指定长度的文章(文章摘要)
- format(value,*args,**kwargs)参考Python的字符串格式化函数
- length左边如果是列表,输出列表的数量;如果是字符串,则输出字符串的长度
- ……
完整的fliter列表:http://jinja.pocoo.org/docs/dev/templates/#builtin-filters
Tests(测试,判断)
Jinja2提供的tests可以用来在语句里对变量或表达式进行测试,如果要测试一个变量,可以在变量后加上“is”和test名,比如:
{%ifuser.ageisequalto42%}{#这里也可以写成...isequalto(42)#} Ha,youare42! {%endif%}
如果要传入参数,可以在test后增加括号,也可以直接写在后面。
常用的test(未说明的均返回True或False):
- defined
- equalto
- escaped
- none
- sequence
- string
- number
- reverse
- replace
- ......
完整的test列表及用法见:TemplateDesignerDocumentation
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
WhitespaceControl(空格控制)
默认的设置:
- 如果末尾有换行符,则去除;
- 其他空格原样保留。
也就是说,下面这几行:
{%ifTrue%} yay {%endif%}
渲染后的结果是这样:
yay
Jinja2语句占据的空行,你自己输出的空格,Tab都将保留。
如果要去掉Jinja2语句占据的空行,可以通过设置Jinja2的环境变量实现:
app.jinja_env.trim_blocks=True app.jinja_env.lstrip_blocks=True
或者像这样手动添加一个减号(注意和%之间没有空格):
{%ifTrue-%} yay {%-endif%}
两者实现的效果相同,如下:
yay
如果语句块的前后都加上减号:
{%-ifTrue-%} yay {%-endif-%}
渲染后会是这样:
yay
通过Jinja2提供的环境变量,你可以设置很多东西,比如分隔符(在和其他的语言产生冲突时,可以通过修改分隔符来解决)。具体见:http://jinja.pocoo.org/docs/dev/api/#jinja2.Environment
Escaping(转义)
有时你会想原样输出一些Jinja2语句和分隔符,对于小的内容,可以使用变量表达式来输出,比如输出一个分隔符:
{{'{{'}}
大的内容块可以使用一个raw块包裹:
{%raw%}
-
{%foriteminseq%}
- {{item}} {%endfor%}
模板继承
你可以创建一个base.html作为基模板,把导航栏、页脚、flash消息、js或css文件等等需要在每一个页面中显示的内容放在基模板里,并添加一个空的块用来放置其他子模板的内容:
{%blockcontent%}{%endblock%}
然后在其他的模板(子模板)里使用这个extends语句继承它,并放置相应的内容到基模板里定义过的空块:
{%extends"base.html"%} {%blockcontent%} 子模板的内容
{%endblock%}
如果想添加内容到在父模板内已经定义的块,可以使用super函数:
{%blocksidebar%}TableOfContents
... {{super()}} {%endblock%}
这样可以避免覆盖父块的内容。
全局函数
常用的全局函数有:
- range([start,]stop[,step])
- lipsum(n=5,html=True,min=20,max=100)为模板生成一些loremipsum。
详细列表见:TemplateDesignerDocumentation
其他内容
内容还有很多,比如行语句、控制流、表达式、宏等。不再一一介绍了(写这种介绍文章太累了……)。
具体见文档的模板部分:
TemplateDesignerDocumentation
相关链接
Jinja主页:Jinja2Documentation
Jinja2文档:Jinja2Documentation
Jinja2文档模板部分:TemplateDesignerDocumentation
Github项目页:pallets/jinja
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。