Flask和Django,以及其它不少Python框架,都默认使用Jinja2
来做为模版引擎。html
在Python中,什么是模版?就是在一个静态HTML加入一些相似变量的标签,而后引擎在渲染这个HTML时候会动态的把变量填入内容,生成一个最终的HTML。
什么是模版引擎?其实就是一种能解析相似Python语言
的标记语言的解释器。python
好比咱们在HTML模版中输入一个<p> {{ post.title }} </p>
,显然这不是真正的HTML语法。可是当Jinja2解释器读取到{{ ...}}
后知道里面是一个变量,那么就把这个变量替换为真正的值,最后翻译出来就变成了<p> 大标题 </p>
这样的HTML内容。api
Jinja2是一个模版语言,只是相似Python,比较符合Python语法,但不彻底相同!app
全部的模版引擎,实际上都差很少,不论是基于VBS语言的ASP模版,仍是基于PHP语言的PHP模版,都不是与本来语言一摸同样,而只是作到尽可能同样而已。框架
注意:Jinja2
模版语言,是不区分缩进的,和纯python不一样。实际上全部模版语言都不区分缩紧。函数
经常使用标记:post
{# 这是注释 #}
{{ post.title }}
,或字典元素{{your_dict['key']}}
,或列表{{your_list[0]}}
{% 开始 %} HTML标签 {% 结束 %}
示例:url
{% if user %} {{ user }} {% else %} hello! {% for index in indexs %} {{ index }} {% endfor %}
一个filter过滤器的本质就是一个function函数。使用格式为:变量名 | 函数
。
它作到的就是,把变量传给函数,而后再把函数返回值做为这个代码块的值。命令行
如:翻译
<!-- 带参数的 --> {{变量 | 函数名(*args)}} <!-- 不带参数能够省略括号 --> {{变量 | 函数名}}
链式调用(管道式):
和命令行的pipline管道同样,能够一次调用多个函数(过滤器),如:
{{ "hello world" | reverse | upper }}
文本块调用(将中间的全部文字都做为变量内容传入到过滤器中):
{% filter upper %} 一大堆文字 {% endfilter %}
字符串操做:
safe:禁用转义 <p>{{ '<em>hello</em>' | safe }}</p> capitalize:把变量值的首字母转成大写,其他字母转小写 <p>{{ 'hello' | capitalize }}</p> lower:把值转成小写 <p>{{ 'HELLO' | lower }}</p> upper:把值转成大写 <p>{{ 'hello' | upper }}</p> title:把值中的每一个单词的首字母都转成大写 <p>{{ 'hello' | title }}</p> reverse:字符串反转 <p>{{ 'olleh' | reverse }}</p> format:格式化输出 <p>{{ '%s is %d' | format('name',17) }}</p> striptags:渲染以前把值中全部的HTML标签都删掉 <p>{{ '<em>hello</em>' | striptags }}</p> truncate: 字符串截断 <p>{{ 'hello every one' | truncate(9)}}</p>
列表操做:
first:取第一个元素 <p>{{ [1,2,3,4,5,6] | first }}</p> last:取最后一个元素 <p>{{ [1,2,3,4,5,6] | last }}</p> length:获取列表长度 <p>{{ [1,2,3,4,5,6] | length }}</p> sum:列表求和 <p>{{ [1,2,3,4,5,6] | sum }}</p> sort:列表排序 <p>{{ [6,2,3,1,5,4] | sort }}</p>
Jinja2是容许自定义函数的,这样在模版中能够重复利用这个自定义函数。Jinja2称之为Macro
宏。
定义方法:
{% macro 函数名(参数) %} 具体的HTML内容 {% endmacro %} <!-- 使用 --> {{ 函数名(参数) }} <!-- 或做为过滤器 --> {{ 变量 | 函数名(参数) }}
关于Jinja2自定义函数的context
上下文和环境变量的问题:
Jinja2的自定义函数“宏”,自己是无法像filter过滤器函数同样使用上下文和环境变量的。
不过能够加上@contextfilter
装饰器达到一样的效果。
导入另外一个文件的自定义函数“宏”:
假设在macro.html
文件中咱们定义了一个函数func()
。
那么如今咱们能够在另外一个文件reference.html
中像python导入模块同样导入它:
{% import 'macro.html' as module %} {{ module.func() }}
Include是咱们经常使用的操做,即定义一个框架模版(父模版),而后一个一个指定性的把子模版引入进来。
框架模版frame.html
以下:
{% include 'header.html' %} {% include 'body.html' %} {% include 'footer.html' %}
咱们能够在一个父模版中定义一个block
代码块,而后在另外一个子模版中“继承”这个父模版,并重写这个block
代码块。
不过通常模版中的父模版,都只是留出一个block
空位,里面不写东西,特地等子模版来实现。
假设如今有一个父模版parent.html
:
{% block HEADER %} 页头部分的HTML内容。 {% endblock HEADER %} {% block BODY %} 正文部分的HTML内容。 {% endblock BODY %} {% block FOOTER %} 页脚部分的HTML内容。 {% endblock FOOTER %}
其中定义了三个block,页头、正文和页脚。
而后咱们就能够定义一个模版child.html
来继承父模版,而且只重写BODY部分:
{% extends 'parent.html' %} {% block BODY %} 由子页面重写改写的的HTML内容,替换父页面的BODY。。。 {% endblock BODY %}
扩展完成后,咱们最终获得的结果是:
{% block HEADER %} 页头部分的HTML内容。 {% endblock HEADER %} {% block BODY %} 由子页面重写改写的的HTML内容,替换父页面的BODY。。。 {% endblock BODY %} {% block FOOTER %} 页脚部分的HTML内容。 {% endblock FOOTER %}
在Flask应用Jinja2模版时,在模版中能够直接调用Flask app中的一些公用变量和方法。
引用Flask的request
对象:
<p> {{ request.url }} </p> <p> {{ request.form.get('name') }} </p>
引用Flask的url_for(...)
方法:
<!-- 它会返回咱们定义的路由`app.route('/index')`所对应的URL --> <p> {{ url_for('index') }} </p> <!-- 它会返回咱们定义的路由`app.route('/post/{post_id}')`所对应的URL --> <p> {{ url_for('post', post_id='127') }} </p>
在模版中,咱们能够引用get_flashed_messages()
方法,获取Flask路由传来的闪现信息
:
{% for msg in get_flashed_messages() %} <p> {{ msg }} </p> {% endfor %}
这种闪现信息是从Flask路由中传来的,只要在路由中发一个flash('hello')
信息,至关于弹了一个alert()
。而后咱们能够在Jinja2的模版中用get_flashed_messages()
得到flash过来的信息列表。