1.Jinja2模板引擎
模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。
使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。
默认情况下,Flask 在程序文件夹中的 templates 子文件夹中寻找模板.
Flask 提供的 render_template 函数把 Jinja2 模板引擎集成到了程序中。render_template 函数的第一个参数是模板的文件名。随后的参数都是键值对,表示模板中变量对应的真实值。
-*- user.html <h1>Hello, {{ name }}!</h1>
from flask import render_template @app.route(‘/user/<name>‘) def user(name): return render_template(‘user.html‘, name=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 variable index: {{ mylist[myintvar] }}</p> <p>A value from an objects method: {{ myobj.somemethod }}</p>
可以使用过滤器修改变量
<h1>Hello, {{ name|capitalize }}</h1>
jinja2的控制结构
if
{% if user %} Hello, {{ user }}! {% else %} Hello, Stranger! {% endif %}
for
<ul> {% for comment in comments %} <li>{{ comment }}</li> {% endfor %} </ul>
宏(macro)(类似函数)
{% macro render_comment(comment) %} <li>{{ comment }}</li> {% endmacro %} <ul> {% for comment in comments %} {{ render_comment(comment) }} {% endfor %} </ul>
为了重复使用宏, 可以将宏保存为单独文件,然后在需要的模板中导入
{% import ‘macros.html‘ as macros %} <ul> {{% for comment in comments %}} {{ macros.render_comment(comment) }} {{% endfor %}} </ul>
需要在多处重复使用的模板片段可以保存为单独的文件,然后再包含在所需的模板中(include)
{{% include ‘common.html‘ %}}
另一种重复使用代码的方法是模板继承
-*- base.html <html> <head> {% block head %} <title> {% block title %} {% endblock %} - My Application </title> {% endblock %} </head> <body> {% block body%} {% endblock %} </body> </html>
block标签定义的元素可在衍生模板中修改
{% extends "base.html" %} {% block title %} Index {% endblock %} {% block head %} {{ super() }} {% endblock %} {% block body %} <h1>Hello, World!</h1> {% endblock %}
extends指明这个模板衍生自base.html
super()用于获取原来的内容
2. 使用Flask-Bootstrap集成Bootstrap
初始化Flask-Bootstrap
from flask.ext.bootstrap import Bootstrap bootstrap = Bootstrap(app)
初始化 Flask-Bootstrap 之后,就可以在程序中使用一个包含所有 Bootstrap 文件的基模板。
这个模板利用 Jinja2 的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中就有用来引入 Bootstrap 的元素。
-*-base.html {% 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"> {% block page_content %}{% endblock %} </div> {% endblock %}
{% extends "base.html" %} {% block title %}Flasky{% endblock %} {% block page_content %} <div class="page-header"> <h1>Hello, {{ name }}!</h1> </div> {% endblock %}
extends指令从Flask-Bootstrap中导入bootstrap/base.html,从而实现模板继承
bootstrap/base.html提供了一个网页框架,引入了Bootstrap中的所有css和javascript
bootstrap/base.html定义了可以衍生模板中重定义的块(块里面的东西就跟普通的bootstrap没什么区别)
Flask-Bootstrap基模板中定义的块
ps:很多块都是 Flask-Bootstrap 自用的,如果直接重定义可能会导致一些问题。
例如,Bootstrap 所需的文件在 styles 和 scripts 块中声明。如果程序需要向已经有内容的块中添加新内容,必须使用 Jinja2 提供的 super() 函数。
so,如果要在衍生模板中添加新的 JavaScript 文件,需要这么定义 scripts 块:
{% block scripts %} {{ super() }} <script type="text/javascript" src="my-script.js"></script> {% endblock %}
3. 自定义错误界面
@app.errorhandler(404) def page_not_found(e): return render_template(‘404.html‘), 404
4. 连接
在模板中直接编写简单路由的 URL 链接不难,但对于包含可变部分的动态路由,在模板中构建正确的 URL 就很困难。而且,直接编写 URL 会对代码中定义的路由产生不必要的依赖关系。如果重新定义路由,模板中的链接可能会失效。
为了避免这些问题,Flask 提供了 url_for() 辅助函数,它可以使用程序 URL 映射中保存的信息生成 URL。
url_for() 函数最简单的用法是以视图函数名(或者 app.add_url_route() 定义路由时使用的端点名)作为参数,返回对应的 URL。
例如,在当前版本的 hello.py 程序中调用 url_for(‘index‘) 得到的结果是 /。调用 url_for(‘index‘, _external=True) 返回的则是绝对地址,在这个示例中是 http://localhost:5000/。
使用 url_for() 生成动态地址时,将动态部分作为关键字参数传入。
例如,url_for(‘user‘, name=‘john‘, _external=True) 的返回结果是 http://localhost:5000/user/john。
传入 url_for() 的关键字参数不仅限于动态路由中的参数。
函数能将任何额外参数添加到查询字符串中。例如,url_for(‘index‘, page=2) 的返回结果是 /?page=2
5. 静态文件
对静态文件的引用被当成一个特殊的路由,即 /static/<filename>。
例如,调用url_for(‘static‘, filename=‘css/styles.css‘, _external=True) 得 到 的 结 果 是 http://localhost:5000/static/css/styles.css。
默认设置下,Flask 在程序根目录中名为 static 的子目录中寻找静态文件。如果需要,可在static 文件夹中使用子文件夹存放文件。
服务器收到前面那个 URL 后,会生成一个响应,包含文件系统中 static/css/styles.css 文件的内容。
2015-05-21