Flask Jinja2模板辅助工具
模板辅助工具
from flask import render_template
@app.route('/')
def index():
return render_template(''index.html'',user=user, movies=movies)
上下文
模板上下文包含了很多变量,其中包括我们调用render_template()函数时手动传入的变量以及Flask默认传入的变量。
除了渲染时传入变量(使用键值对的形式),也可以在模板中定义使用set标签变量:
{% set navigation = [('/', 'Home'), ('/about', 'About')] %}
{# 也可以将一部分模板数据定义为变量 ,如下 #}
{% set navigation %}
<li><a herf='/'>Home</a>
<li><a href='/about'>About</a>
{% endset %}
内置上下文变量
Flask在模板上下文中提供了一些内置变量,可以在模板中直接使用:
![](https://img.haomeiwen.com/i3512339/f0cd6642e2a1ac92.png)
自定义上下文变量
使用注册模板上下文处理函数:@app.context_processer
如果多个模板都需要使用同一变量,那么比起在多个视图函数中重复传入,更好的方法是能够设置一个模板全局变量。Flask提供了一个app.context_processor
装饰器,可以用来注册模板上下文处理函数,它可以帮我们完成统一传入变量的工作。
模板上下文处理函数需要返回一个包含变量键值对的字典。
@app.context_processor # 这里没有括号
def inject_human():
human = " I am human"
return {"human":human}
# 等价于
app.context_processor(lambda:{"human":"I am human"})
当我们调用render_template()
函数渲染任意一个模板时,所有使用app.context_processor
装饰器注册的模板上下文处理函数(包括Flask内置的上下文处理函数)都会被执行,这些函数的返回值会被添加到模板中,因此我们可以在模板中直接使用 human
变量。
和在render_template()函数中传入变量类似,除了字符串、列表等数据结构,也可以传入函数、类或类实例。
全局对象
全局函数
- 内置全局函数
List of Global Functions: http://jinja.pocoo.org/docs/2.10/templates/#list-of-global-functions
Jinja2在模板中默认提供了一些全局函数,如下:
![](https://img.haomeiwen.com/i3512339/20031cdb2d4db730.png)
除了Jinja2内置的全局函数,Flask也在模板中内置了两个全局函数:
![](https://img.haomeiwen.com/i3512339/7f5991e5780c6dca.png)
-
自定义全局函数
除了使用app.context_processor
注册模板上下文处理函数来传入函数,也可以使用app.template_global
装饰器直接将函数注册为模板全局函数。
@app.template_global() # 参数为函数别名
def bar():
return "I am bar"
默认使用函数的原名称传入模板,在app.template_global()
装饰器中使用name参数可以指定一个自定义名称。app.template_global()仅能用于注册全局函数。
过滤器
- 内置过滤器
List of Builtin Filters: http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters
在Jinja2中,过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数,过滤器和变量用一个竖线(管道符号)隔开,需要参数的过滤器可以像函数一样使用括号传递。
格式:{{name|default("John")}}
Jinja2内置过滤器:
![](https://img.haomeiwen.com/i3512339/2b5522fe7926f6eb.png)
![](https://img.haomeiwen.com/i3512339/b4c4584e6684b06c.png)
在使用过滤器时,列表中过滤器函数的第一个参数表示被过滤的变量值(value)或字符串(s),即竖线符号左侧的值,其他的参数可以通过添加括号传入。
另外,过滤器可以叠加使用,下面的示例为name变量设置默认值, 并将其标题化
<h1>Hello, {{ name|default('陌生人')|title }}!</h1>
- 自定义过滤器
from flask import Markup
@app.template_filter() # 参数为过滤器别名
def musical(s):
return s+Markup(' ♫')
用法: {{name | musical}}
测试器
在Jinja2中,测试器(Test)是一些用来测试变量或表达式,返回布尔值(True或False)的特殊函数。比如,number测试器用来判断一个变量或表达式是否是数字,我们使用 is
连接变量和测试器:
{% if age is number %}
{{ age * 10}}
{% else %}
无效的数字
{% endif %}
-
内置测试器
在使用测试器时,is的左侧是测试器函数的第一个参数(value), 其他参数可以添加括号传入,也可以在右侧使用空格连接 :
{% if foo is saemas(bar) %}
等价于
{% if foo is saemas bar %}
- ** 自定义测试器 **
@app.template_test() # # 参数为测试器别名
def baz(n):
if n == 'test':
return True
return False
测试器的名称默认为函数名称,你可以在app.template_test()中使用name关键字指定自定义名称。测试器函数需要接收被测试的值作为输入,返回布尔值.
模板环境对象
在Jinja2中,渲染行为由jinja2.Enviroment类控制,所有的配置选 项、上下文变量、全局函数、过滤器和测试器都存储在Enviroment实例上。当与Flask结合后,我们并不单独创建Enviroment对象,而是使用Flask创建的Enviroment对象,它存储在app.jinja_env属性上。
模板环境中的全局函数、过滤器和测试器分别存储在Enviroment对象的globals、filters和tests属性中,这三个属性都是字典对象。除了使用
Flask提供的装饰器和方法注册自定义函数,我们也可以直接操作这三个字典来添加相应的函数或变量,这通过向对应的字典属性中添加一个键值对实现,传入模板的名称作为键,对应的函数对象或变量作为值。
app.jinja_env.globals['bar'] = bar # 添加自定义全局函数
app.jinja_env.globals['foo'] = foo # 添加全局变量
app.jinja_env.filters['smiling'] = smiling # 添加自定义过滤器
app.jinja_env.tests['baz'] = baz # 添加自定义测试器