模板輔助工具
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在模板上下文中提供了一些內置變量,可以在模板中直接使用:
自定義上下文變量
使用註冊模板上下文處理函數:@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在模板中默認提供了一些全局函數,如下:
除了Jinja2內置的全局函數,Flask也在模板中內置了兩個全局函數:
- 自定義全局函數
除了使用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內置過濾器:
在使用過濾器時,列表中過濾器函數的第一個參數表示被過濾的變量值(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 # 添加自定義測試器