模板

在上篇中,我们只渲染了一行毫无特点的字符串,这太逊了。通过本篇的学习,我们将渲染出达到上世纪九十年代水准的完整网页!

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 是块的名称,允许更换,但必须保证它是唯一的。