第二章
一、何谓模板
模板:我理解就是建立一套固定化格式的内容(将一些通用共同的部分分离成独立的部分),通过传入的参数或数据的不同,展示的部分内容随着改动。所以,改动的内容就会减少很多,提高开发效率。
1、假设我们要在首页显示一个问候
由于我们还没有注册的客户信息,为了实现这个功能,我们先模拟出一个用户。
user = {'username': 'Miguel'}
2、通过视图函数构建Html问候页面
app/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>'''
Tip:
@app.route方法中的参数——endpoint(端点):
端点类似程序中一组逻辑处理单元的ID,该ID对应的代码决定了对此ID请求应该作出何种响应。
如果我们构建两个url,@app.route(’/admin’,greeting)和@app.route(’/user’,greeting):端点效果如下:
/admin/greeting
/user/greeting
@app.route('/user/<[int|float|path]:username>') #<username>是一个命名变量,冒号前边的是一个转换器,默认是path,例如‘/’
@app.route('/login', methods=['GET', 'POST']) #可以添加其他的访问方式
3、在显示页拼写业务源码的弊端
安装上一章提到的运行方法,就可以运行出结果;
Home Page --Microblog
Hello,Miguel!
如果只有少量的几个用户,我们可以这样拼凑代码。如果交互项一多,维护代价就很大。而且这些内容的复用性就很低。
为了降低各模块之间的耦合性,根据网页设计的MVVM框架。应尽可能的把逻辑层(数据、模型)与视图层(页面结构)等独立出来。
也就有了模板这个概念
4、建立整个APP模板块
为了统一管理各模板,新建一个名为emplate的文件夹,此文件夹下的页面可以相互引用。
>mkdir app/templates
Tip:如果我们的应用是个模块,这个文件夹应该与模块同级;如果它是一个包,那么这个文件夹作为包的子目录
5、实现展示结构与数据部分的分离
通过Flask框架下的jinjia2引擎,把上边的html文件改进一下。
app/templates/index.html。
<html>
<head>
<title>{{ title }} - Microblog</title> /*这个双大括号就是占位符:用来引用变量为title数据的。*/
</head>
<body>
<h1>Hello, {{ user.username }}!</h1> /*同理,user.username是user字典里用户名字。*/
</body>
</html>
render_template(template_name_or_list, **context):
第一个参数是模板名称,第二个可变参数是模板中的传参赋值。
Tip:
首页展示的时候,自动更新数据的过程,专业术语就叫:渲染。
jinjia2的两大功能:
1、控制结构{% %},例如{% for|if %},结尾不需要冒号;
2、变量{{ variable}}, 例如{{name}}。{{}}是一个变量占位符。
6、网络请求路径图(图是引用别人的,跟例子略有差异,不过执行顺序应该是一致的。):
二、jinjia2的控制结构语法
1、if结构{% .if…else…endif %}
<html>
<head>
{% if title %} /*此处的title是引用自routes.py中render_template中参数值*/
<title>{{ title }} - Microblog</title> /*title同上*/
{% else %}
<title>Welcome to Microblog!</title>
{% endif %}
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
2、循环结构{% for …in…endfor %}
<body>
<h1>Hi, {{ user.username }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
</body>
三、模板继承
1、基础模板
当开发网页的时候,一般每个网页都有一个导航栏,为了减少重复代码开发,可以把导航栏提炼出来,形成一个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>
2、继承模板
app/templates/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 %}