模板有助于实现页面展现和业务逻辑之间的分离。 在Flask中作用Jinja2模板,模板被编写为单独的文件,存储在应用程序包内的templates文件夹中。
1、在app下创建一个存储模板的目录templates,创建第一个模板文件,这个文件写在app/templates/index.html中:
<html>
<head>
<title>{{ title }} - Microblog</title>
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
修改视图函数index()如下:
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
return render_template('index.html', title='Home', user=user)
现在启动应用,看一看前端与后端如何分离并协同工作的吧!
2、Jinja2模板如何使用条件语句,模板支持{% %}内添加控制语句
更改index.html如下所示:
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog!</title>
{% endif %}
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
现在,如果视图函数忘记给渲染函数传入一个名为title的关键字参数,那么模板将显示一个默认的标题,而不是显示一个空的标题。 你可以通过在视图函数的render_template()调用中去除title参数来试试这个条件语句是如何生效的。
3、Jinja2模板如何使用循环。
使用模拟对象的把戏来创建一些模拟用户和动态,调整视图函数index():
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
posts = [
{
'author': {'username': 'John'},
'body': 'Beautiful day in Portland!'
},
{
'author': {'username': 'Susan'},
'body': 'The Avengers movie was so cool!'
}
]
return render_template('index.html', title='Home', user=user, posts=posts)
Jinja2提供了for控制结构来应对这类问题:
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog</title>
{% endif %}
</head>
<body>
<h1>Hi, {{ user.username }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
</body>
</html>
玩玩这个新版本的应用程序,看看模板如何调度以展现视图函数传入的所有用户动态。
4、模板的继承
Jinja2有一个模板继承特性,就是将所有模板中相同的部分转移到一个基础模板中,然后再从它继承过来。
定义一个名为base.html的基本模板,其中包含一个简单的导航栏,以及之前实现的标题逻辑。 需要在模板文件app/templates/base.html中编写代码如下:
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog</title>
{% endif %}
</head>
<body>
<div>Microblog: <a href="/index">Home</a></div>
<hr>
{% block content %}{% endblock %}
</body>
</html>
在这个模板中,使用block控制语句来定义派生模板可以插入代码的位置。 block被赋予一个唯一的名称,派生的模板可以在提供其内容时进行引用。
通过从基础模板base.html继承HTML元素,现在可以简化模板index.html了:
{% extends "base.html" %}
{% block content %}
<h1>Hi, {{ user.username }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
{% endblock %}
基础模板base.html接手页面的布局之后,就可以从index.html中删除所有这方面的元素,只留下内容部分。 extends语句用来建立了两个模板之间的继承关系,这样Jinja2才知道当要求呈现index.html时,需要将其嵌入到base.html中。 而两个模板中匹配的block语句和其名称content,让Jinja2知道如何将这两个模板合并成在一起。 现在,扩展应用程序的页面就变得极其方便了。