在上篇中,我们只渲染了一行毫无特点的字符串,这太逊了。通过本篇的学习,我们将渲染出达到上世纪九十年代水准的完整网页!
1 渲染与业务分离
稍作修改的路由文件 routes.py
如下。
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
return '''
<html>
<head>
<title>Home Page - Microblog</title>
</head>
<body>
<h1>Hello, ''' + user['username'] + '''!</h1>
</body>
</html>'''
从 routes.py
中抽出 app/templates/index.html
<html>
<head>
<title>{{ title }} - Microblog</title>
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
显然,由于 app/templates/index.html
的抽出, routes.py 被简化。
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)
render_template 是 flask 提供的渲染模板函数。 render_template 暗中调用了 Flask 的内置模板引擎 Jinja2 , Jinja2 负责用参数替换 {{…}}
。注意第一个参数 index.html
没有注明详细路径,可见冥冥之中自有默认。
2 语句
2.1 控制语句
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog!</title>
{% endif %}
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
2.2 循环语句
<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>
2.3 继承派生
父类模板 app/template/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>
子类模板 app/template/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 %}
content 是块的名称,允许更换,但必须保证它是唯一的。