在通常的 Web 程序里,访问一个地址一般会返回一个包含各种信息的 HTML 页面。由于咱们的程序是动态的,页面中的某些信息须要根据不一样的状况来进行调整,好比对登陆和未登陆用户显示不一样的信息,因此页面须要在用户访问时根据程序逻辑动态生成。html
咱们把包含变量和运算逻辑的 HTML 或其余格式的文本叫作模板,执行这些变量替换和逻辑计算工做的过程被称为渲染,这个工做由咱们这一章要学习使用的模板渲染引擎——Jinja2 来完成。git
按照默认的设置,Flask 会从程序实例所在模块同级目录的 templates 文件夹中寻找模板,咱们的程序目前存储在项目根目录的 app.py 文件里,因此咱们要在项目根目录建立这个文件夹:github
$ mkdir templates复制代码
在社交网站上,每一个人都有一个主页,借助 Jinja2 就能够写出一个通用的模板:flask
<h1>{{ username }}的我的主页</h1>
{% if bio %}
<p>{{ bio }}</p> {# 这里的缩进只是为了可读性,不是必须的 #}
{% else %}
<p>自我介绍为空。</p>
{% endif %} {# 大部分 Jinja 语句都须要声明关闭 #}复制代码
Jinja2 的语法和 Python 大体相同,你在后面会陆续接触到一些常见的用法。在模板里,你须要添加特定的定界符将 Jinja2 语句和变量标记出来,下面是三种经常使用的定界符:数据结构
{{ ... }}
用来标记变量。{% ... %}
用来标记语句,好比 if 语句,for 语句等。{# ... #}
用来写注释。模板中使用的变量须要在渲染的时候传递进去,具体咱们后面会了解。app
咱们先在 templates 目录下建立一个 index.html 文件,做为主页模板。主页须要显示电影条目列表和我的信息,代码以下所示:函数
templates/index.html:主页模板学习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ name }}'s Watchlist</title>
</head>
<body>
<h2>{{ name }}'s Watchlist</h2>
{# 使用 length 过滤器获取 movies 变量的长度 #}
<p>{{ movies|length }} Titles</p>
<ul>
{% for movie in movies %} {# 迭代 movies 变量 #}
<li>{{ movie.title }} - {{ movie.year }}</li> {# 等同于 movie['title'] #}
{% endfor %} {# 使用 endfor 标签结束 for 语句 #}
</ul>
<footer>
<small>© 2018 <a href="http://helloflask.com/tutorial">HelloFlask</a></small>
</footer>
</body>
</html>复制代码
为了方便对变量进行处理,Jinja2 提供了一些过滤器,语法形式以下:测试
{{ 变量|过滤器 }}复制代码
左侧是变量,右侧是过滤器名。好比,上面的模板里使用 length
过滤器来获取 movies
的长度,相似 Python 里的 len()
函数。网站
提示 访问 http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-filters 查看全部可用的过滤器。
为了模拟页面渲染,咱们须要先建立一些虚拟数据,用来填充页面内容:
app.py:定义虚拟数据
name = 'Grey Li'
movies = [
{'title': 'My Neighbor Totoro', 'year': '1988'},
{'title': 'Dead Poets Society', 'year': '1989'},
{'title': 'A Perfect World', 'year': '1993'},
{'title': 'Leon', 'year': '1994'},
{'title': 'Mahjong', 'year': '1996'},
{'title': 'Swallowtail Butterfly', 'year': '1996'},
{'title': 'King of Comedy', 'year': '1999'},
{'title': 'Devils on the Doorstep', 'year': '1999'},
{'title': 'WALL-E', 'year': '2008'},
{'title': 'The Pork of Music', 'year': '2012'},
]复制代码
使用 render_template()
函数能够把模板渲染出来,必须传入的参数为模板文件名(相对于 templates 根目录的文件路径),这里即 'index.html'
。为了让模板正确渲染,咱们还要把模板内部使用的变量经过关键字参数传入这个函数,以下所示:
app.py:返回渲染好的模板做为响应
from flask import Flask, render_template
# ...
@app.route('/')
def index():
return render_template('index.html', name=name, movies=movies)复制代码
为了更好的表示这个视图函数的做用,咱们把原来的函数名 hello
改成 index
,意思是“索引”,即主页。
在传入 render_template()
函数的关键字参数中,左边的 movies
是模板中使用的变量名称,右边的 movies
则是该变量指向的实际对象。这里传入模板的 name
是字符串,movies
是列表,但可以在模板里使用的不仅这两种 Python 数据结构,你也能够传入元组、字典、函数等。
render_template()
函数在调用时会识别并执行 index.html 里全部的 Jinja2 语句,返回渲染好的模板内容。在返回的页面中,变量会被替换为实际的值(包括定界符),语句(及定界符)则会在执行后被移除(注释也会一并移除)。
如今访问 http://localhost:5000/ 看到的程序主页以下图所示:
这一章咱们编写了一个简单的主页。结束前,让咱们提交代码:
$ git add .
$ git commit -m "Add index page"
$ git push复制代码
提示 你能够在 GitHub 上查看本书示例程序的对应 commit:17b579d