第一节说了通常Flask程序中,需要templates文件夹和static的结构,其中templates主要是HTML模板。
模板是一个包含响应文本的文件, 其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。 使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板, Flask 使用了一个名为 Jinja2 的强大模板引擎。
Jinja2模板
Jinja2模板引擎简单示例
官方文档在这里:Jinja2 ,下面是一个最简单的Jinja模板栗子:
新建:templates/index.html文件
<h1>Hello World!</h1>
这个对应的是前一节中的index()函数,不包含变量,在Jinja模板中,如果包含变量,需要用两个花括号标识。
新建:templates/user.html文件
<h1>hello {{ name }}</h1>
模板渲染
默认情况下, Flask 在程序文件夹中的 templates 子文件夹中寻找模板。在下一个 hello.py版本中,要把前面定义的模板保存在 templates 文件夹中,并分别命名为 index.html 和 user.html。
对上一节中的例子进行修改,如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/user/<name>')
def user(name):
return render_template('user.html', name=name)
首先导入flask类以及Jinja模板,完成程序初始化之后,进行模板渲染。render_template 函数的第一个参数是模板的文件名。 随后的参数都是键值对,表示模板中变量对应的真实值。在这段代码中,第二个模板收到一个名为 name 的变量。
在上面的例子中,左边的“name”表示参数名,就是模板中使用的占位符;右边的“name”是当前作用域中的变量,表示同名参数的值。
变量
变量类型
上面的例子中{{ name }} 结构表示一个变量,这是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。
Jinja模板中能够识别的模板类型很多,不止上例中简单的类型,还包括列表、字典和对象等,同样举个栗子。
<p>A value from a dictionary: {{ mydict['key'] }}.</p>
<p>A value from a list: {{ mylist[3] }}.</p>
<p>A value from a list, with a variable index: {{ mylist[myintvar] }}.</p>
<p>A value from an object's method: {{ myobj.somemethod() }}.</p>
变量过滤器
在Jinja模板中,可以使用过滤器来修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述模板以首字母大写形式显示变量 name 的值:
hello, {{ name|capitalize }}
capitalize过滤器的作用是把值的首字母转换成大写,其他字母转换成小写。Jinja2变量还存在其他过滤器。
控制结构
Jinja2 提供了多种控制结构,可用来改变模板的渲染流程。本节使用简单的例子介绍其中最有用的控制结构。
举几个栗子:
if控制结构:
{{ % if user %}}
hello, {{ user }}
{{% else %}}
hello, world
{{% endif % }}
for循环结构:
{% for comment in comments %}
<li>{{ comment }}</li>
{% endfor %}
模板继成
重复继承代码有一种很有效的方式就是模板继承,首先,我们需要在templates文件夹中创建一个base.html的基模板。在其他的视图模板中直接引入基模板就可以了。
举个栗子:
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %} Flasky</title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
像html中的标签一样,使用类似{% block head %}以及闭合标签{% endblock %}。