模块是一个包含响应文本的文件,其中包含占用位变量表示的动态部分,其具体值只在请求的上下文中才知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模块,Flask使用一个名为Jinja2的强大模板引擎。
一、Jinja2模板引擎
形式最简单的Jinja2模板就是一个包含响应文本的文件。
<h1>Hello,World!</h1> <h1>Hello,{{name}}!</h1>
1、渲染模板
默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板。在下一个hello.py版本中,要把前面定义的模板保存在templates文件夹中,并分别命名为index.html和user.html。
#!/usr/bin/env python from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/user/<name>') def user(name): return render_template('user.html',name=name) if __name__ == '__main__': app.run()
Flask提供的render_template函数把Jinja模块引擎集成到了程序中。
2、变量
模板中使用的{{name}}结构表示一个变量,它是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。
Jinja2能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。在模板中使用变量的一些实例如下
<p>a value from a dictionary: {{ mydict['key'] }}</p> <p>a value from a list:{{ mylist[3] }}</p> <p>a value from a list,with a varliable index:{{ mylist[myintavr] }}</p> <p>a value from a objects method:{{ myobj.somemethod() }}</p>
Jinja2变量过滤器
过滤器名 | 说明 |
safe | 、渲染时不转义 |
capitalize |
把值得首字母转换成大写,其他字母转换成小写 |
lower | 把值转换成小写形式 |
upper | 把值转换成大写形式 |
title | 把值中每个单词的首字母都转换成大写 |
trim | 把值的首位空格去掉 |
striptags | 渲染之前把值中所有HTML标签都删除 |
3、控制结构
在模板中使用条件控制语句:
{% if user %} Hello,{{ user }}! {% else %} Hello,Stranger! {% endif %}
<ul> {% for commet in commets %} <li>{{ commet }}</li> {% end for %} </ul>
Jinja2还支持宏,类似于Python代码中的函数。例如:
{% macro render_commet(commet) %} <li>{{ commet }}</li> {% endmacro %} <ul> {% for commet in commets %} {{ render_commet(commet) }} {% endfor %} </ul>
为了重复使用宏,我们可以将其保存在单独的文件中,然后在需要使用的模板中导入:
{% import 'macros.html' as macros %} <ul> {% for commet in commets %} {{ macros.render_commet(commet) }} {% endfor %} </ul>
另一种重复使用代码的强大方式是模板继承,它类似于Python代码中的类继承。首先创建一个名为base.html的基模板:
<html> <head> {% block head %} <title>{% block title %}{% endblock %} - My Application</title> {% endblock %} </head> <body> {% block body %} {% endblock %} </body> </html>
二、使用Flask-Bootstrap集成Twitter Bootstrp
Bootstrap是客户端架构,因此不会直接涉及服务器。服务器要做的知识提供引用了Bootstrap层叠样式表(CSS)和Javascript文件的HTML响应,并在HTML/CSS和Javascript代码中实例化所需组件。这些操作最理想的执行场所就是模板。
#初始化 Flask-bootstrap from flask.ext.bootstrap import Bootstrap #... bootstrap = Bootstrap(app)
初始化Flask-Bootstrap之后,就可以在程序中使用一个包含所有Bootstrap文件的基模板。
{% extends "bootstrap/base.html" %} {% block title %}Flasky{% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> <div class="page-header"> <h1>Hello,{{ name }}!</h1> </div> </div> {% endblock %}
三、自定义错误界面
#自定义错误界面 #!/usr/bin/env python from flask import Flask,render_template app = Flask(__name__) @app.errorhandler(404) def page_not_found(e): return render_template('404.html'),404 @app.errorhandler(500) def internal_server_error(e): return render_template('500.html'),500 if __name__ == '__main__': app.run()
四:链接
Flask提供url_for()辅助函数,它可以使用程序URL映射中保存的信息生成URL。
url_for()函数最简单的用法是以视图函数名(或者app.add_url_route()定义路由时使用的端点名)作为参数,返回对应的URL。
使用url_for()生成动态地址时,将动态部分作为关键字参数传入。例如,url_for('user',name='john',_external=True)
五、静态文件
默认设置下,Flask在程序根目录中名为static的子目录中寻找静态文件。如果需要,可在static文件夹中使用子文件夹存放文件。
#定义收藏夹图标 {% block head %} {{ super() }} <link rel="shortcut icon" href="{{ url_for('static',filename='favicon.ico') }}" type="image/x-icon"> <link rel="icon" href="{{ url_for('static',filename='favicon.ico') }}" type="image/x-icon"> {% endblock %}
六、使用Flask-Moment本地化日期和时间
Flask-Moment是一个Flask程序扩展,能把moment.js集成到Jinja2模板中。
#初始化Flask-Moment from flask.ext.moment import Moment moment = Moment(app)
#引入moment.js库 {% block scripts %} {{ super() }} {{ moment.include_moment() }} {% endblock %}
#!/usr/bin/env python from flask import Flask,render_template app = Flask(__name__) from datetime import datetime from flask_moment import Moment moment = Moment(app) @app.route('/') def index(): return render_template('index.html', current_time=datetime.utcnow()) if __name__ == '__main__': app.run()