Flask模板引擎之Jinja2语法介绍


Posted in Python onJune 26, 2019

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,可以去读它的文档:Jinja2 Documentation。

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)
{# ... #} 注释
# ... ## 行语句(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(', ') }}

常用的内置过滤器:

  • 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 左边如果是列表,输出列表的数量;如果是字符串,则输出字符串的长度
  • ……

完整的fliter列表:http://jinja.pocoo.org/docs/dev/templates/#builtin-filters

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列表及用法见: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(空格控制)

默认的设置:

  1. 如果末尾有换行符,则去除;
  2. 其他空格原样保留。

也就是说,下面这几行:

<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 %}

模板继承

你可以创建一个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。

详细列表见:Template Designer Documentation

其他内容

内容还有很多,比如行语句、控制流、表达式、宏等。不再一一介绍了(写这种介绍文章太累了……)。

具体见文档的模板部分:

Template Designer Documentation 

相关链接

Jinja主页:Jinja2 Documentation

Jinja2文档:Jinja2 Documentation

Jinja2文档模板部分:Template Designer Documentation

Github项目页:pallets/jinja

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python生成随机mac地址的方法
Mar 16 Python
用Python计算三角函数之atan()方法的使用
May 15 Python
python Django批量导入不重复数据
Mar 25 Python
利用python画一颗心的方法示例
Jan 31 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
python 筛选数据集中列中value长度大于20的数据集方法
Jun 14 Python
python简易远程控制单线程版
Jun 20 Python
pandas 条件搜索返回列表的方法
Oct 30 Python
Python 通过打码平台实现验证码的实现
May 13 Python
Python 音频生成器的实现示例
Dec 24 Python
Python之Matplotlib文字与注释的使用方法
Jun 18 Python
教你使用TensorFlow2识别验证码
Jun 11 Python
如何使用Python实现自动化水军评论
Jun 26 #Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
Jun 26 #Python
Python 数据可视化pyecharts的使用详解
Jun 26 #Python
python 实现交换两个列表元素的位置示例
Jun 26 #Python
python之信息加密题目详解
Jun 26 #Python
实例详解Python模块decimal
Jun 26 #Python
Python3之不使用第三方变量,实现交换两个变量的值
Jun 26 #Python
You might like
给初学者的30条PHP最佳实践(荒野无灯)
2011/08/02 PHP
PHP中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
php图像处理函数imagecopyresampled用法详解
2016/12/02 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
JavaScript语言中的Literal Syntax特性分析
2007/03/08 Javascript
JavaScript中的Document文档对象
2008/01/16 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
javascript获得CheckBoxList选中的数量
2009/10/27 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
2014/05/11 Javascript
JavaScript中伪协议 javascript:使用探讨
2014/07/18 Javascript
JAVA四种基本排序方法实例总结
2015/07/24 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
2016/08/11 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
input输入框内容实时监测(附代码)
2017/08/15 Javascript
jqueryUI tab标签页代码分享
2017/10/09 jQuery
JavaScript实现精美个性导航栏筋斗云效果
2017/10/29 Javascript
vue init失败简单解决方法(终极版)
2017/12/22 Javascript
详解如何webpack使用DllPlugin
2018/09/30 Javascript
HTML+JS实现“代码雨”效果源码(黑客帝国文字下落效果)
2020/03/17 Javascript
探索node之事件循环的实现
2020/10/30 Javascript
探索Python3.4中新引入的asyncio模块
2015/04/08 Python
使用基于Python的Tornado框架的HTTP客户端的教程
2015/04/24 Python
Python使用Django实现博客系统完整版
2020/09/29 Python
Python wxpython模块响应鼠标拖动事件操作示例
2018/08/23 Python
html2canvas生成清晰的图片实现打印的示例代码
2019/09/30 HTML / CSS
SNIDEL官网:日本VIVI杂志人气少女第一品牌
2020/03/12 全球购物
我的applet原先好好的, 一放到web server就会有问题,为什么?
2016/05/10 面试题
计算机网络毕业生自荐信
2013/10/01 职场文书
小学生保护环境倡议书
2014/05/15 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
环卫处个人工作总结
2015/03/04 职场文书
Pandas 稀疏数据结构的实现
2021/07/25 Python
Redis 持久化 RDB 与 AOF的执行过程
2021/11/07 Redis
python 远程执行命令的详细代码
2022/02/15 Python
MySQL Server 层四个日志
2022/03/31 MySQL