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处理csv数据的方法
Mar 11 Python
举例讲解Django中数据模型访问外键值的方法
Jul 21 Python
轻松实现python搭建微信公众平台
Feb 16 Python
Python中如何获取类属性的列表
Dec 26 Python
python利用Guetzli批量压缩图片
Mar 23 Python
python或C++读取指定文件夹下的所有图片
Aug 31 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
Nov 05 Python
python将四元数变换为旋转矩阵的实例
Dec 04 Python
Virtualenv 搭建 Py项目运行环境的教程详解
Jun 22 Python
Python使用socket模块实现简单tcp通信
Aug 18 Python
python图片合成的示例
Nov 09 Python
Python制作动态字符画的源码
Aug 04 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
编译问题
2006/10/09 PHP
用PHP和MySQL保存和输出图片
2006/10/09 PHP
详解EventDispatcher事件分发组件
2016/12/25 PHP
Laravel如何友好的修改.env配置文件详解
2017/06/07 PHP
jquery判断小数点两位和自动删除小数两位后的数字
2014/03/19 Javascript
Javascript中的方法和匿名方法实例详解
2015/06/13 Javascript
BootStrap实用代码片段之一
2016/03/22 Javascript
JavaScript中instanceof运算符的使用示例
2016/06/08 Javascript
使用jquery.qrcode.js生成二维码插件
2016/10/17 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
vue todo-list组件发布到npm上的方法
2018/04/04 Javascript
Vue 中axios配置实例详解
2018/07/27 Javascript
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
详解微信小程序的不同函数调用的几种方法
2019/05/08 Javascript
javascript中如何判断类型汇总
2019/05/14 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
扫微信小程序码实现网站登陆实现解析
2019/08/20 Javascript
修改layui的后台模板的左侧导航栏可以伸缩的方法
2019/09/10 Javascript
TypeScript 运行时类型检查补充工具
2020/09/28 Javascript
[50:28]LGD女子学院第三期 DOTA2复仇之魂教学
2013/12/24 DOTA
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
Python连接Redis的基本配置方法
2018/09/13 Python
详解Python中的各种转义符\n\r\t
2019/07/10 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
2020/04/20 Python
Pytorch转onnx、torchscript方式
2020/05/25 Python
浅谈django channels 路由误导
2020/05/28 Python
美国玛丽莎收藏奢华时尚商店:Marissa Collections
2016/11/21 全球购物
乡镇庆八一活动方案
2014/02/02 职场文书
人事文员岗位职责
2014/02/16 职场文书
质量承诺书格式
2014/05/20 职场文书
软件售后服务方案
2014/05/29 职场文书
烟台的海导游词
2015/02/02 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle