宏
宏(macro)是Jinja2提供的一個很有用的特性,它就好比Python中的函數。通過宏可以把一部分模板代碼封裝到宏裏,使用傳遞的參數來構建內容,最後返回構建後的內容。
爲了便於管理,我們可以把宏存儲在單獨的文件裏。
例:
新建macros.html文件
{% macro qux(amount=1) %}
{% if amount==1 %}
I am qux
{% elif amount>=1 %}
We are qux
{% endif %}
{% endmacro %}
在使用時要用import語句來導入它,然後作爲函數調用。
{% from "macros.html" import qux %}
...
{{ qux(amount=5) }}
使用宏時的上下文問題
在Jinja2中,處於性能考慮,默認情況下包含一個局部模板會傳遞當前上下文到局部模板中,,但導入不會。具體來說,當我們使用render_template()函數來渲染一個foo.html模板時,這個foo.html模板上下文中包含下列對象:
- Flask使用內置的模板上下文處理函數提供的g、session、config、request。
- 擴展使用內置的模板上下文處理函數提供的變量。
- 自定義模板上下文處理器傳入的變量。
- 用render_template()函數傳入的變量。
- Jinja2和Flask內置及自定義全局對象。
- Jinja2內置自定義過濾器。
- Jinja2內置自定義測試其。
用include標籤插入的局部模板同樣可以使用上述上下文中的變量和函數。而導入另一個非被直接渲染的模板時,這個模板僅包含下列對象:
- Jinja2和Flask內置及自定義全局對象。
- Jinja2內置自定義過濾器。
- Jinja2內置自定義測試其。
如果要在導入的宏中使用第一個列表的2、3、4項,就需要在導入時使用with context 聲明傳入當前模板的上下文。
{% from 'macros.html' import foo with context %}
使用宏加載靜態資源
寫一個用於加載靜態資源的宏:
{% macro static_file(type, filename, local=True) %}
{% if local %}
{% set filename_or_url = url_for('static',filename=filename_or_url) %}
{% endif %}
{% if type=="css" %}
<link rel="stylesheet" href="{{ filename_or_url }}" type="text/css">
{% elif type=='js' %}
<script type="text/javascript" src="{{ filename_or_url }}"></script>
{% elif type=="icon"%}
<link rel="icon" href="{{ filename_or_url }}">
{% endif %}
{% endmacro %}
在模板中導入宏
{% from macros.html import static_file %}
使用這個宏代替原來的<link>標籤加載CSS文件
也可以使用這個函數從CND加載資源,只需要將關鍵字參數local=False,並傳入URL
static_file('css','https://......',local=False)
消息閃現
Flask中存在flash()函數,它可以用來"閃現"需要顯示給用戶的消息。例如登陸成功後顯示"歡迎回來"。在視圖中調用flash()函數,傳入消息內容即可"閃現"一條消息。它並不是像HTML的alert()一樣立刻彈出一條消息。實際上,使用flash()函數發送的消息會存儲在session中,我們需要在模板中使用get_flashed_messages()獲取消息並顯示。
@app.route('/flash') def just_flash(): flash('I am flash, who is looking for me?') return redirect(url_for('index'))
建立一個用來“閃現”的視圖函數。“閃現”一條消息,然後返回index。
在base.html中渲染flash消息
<main> {% for message in get_flashed_messages() %} <div class="alert">{{ message }}</div> {% endfor %} {% block content %}{% endblock %} </main>
爲了便於測試,在index.html中添加新的標籤,指向/flash。
<li><a href="{{ url_for('just_flash') }}">Flash something</a></li>
點擊Flash something表現,顯示‘閃現’的消息。這個頁面的cookie中沒有session。因爲當調用get_flashed_messages()函數時,session中存儲的所有消息都會被刪除。如果此時刷新頁面,會發現重新加載後的頁面不再出現這flash的消息。
製作404頁面
學習自定義錯誤頁面,就像學每個語言都要寫“Hello World”一樣,幾乎成爲了約定俗成的流程233。
寫一個404頁面的子模板。當然大家要是想單獨寫一個全新的頁面什麼的也行。
{% extends 'base.html' %} {% block title %}404 - PAGE NOT FOUND{% endblock %} {% block content %} <h1>Page not found</h1> <p>You are lost..</p> {% endblock %}
我的404頁面模板如上,繼承base模板,再添加一些簡單的標籤意思意思233。
錯誤處理函數需要附加@app.errorhandler()裝飾器,並傳入錯誤碼作爲參數。處理函數本身則需要接收異常類作爲參數,並在返回值中註明對應的HTTP狀態碼。
@app.errorhandler(404) def page_not_found(e): return render_template('error/404.html'), 404
異常對象e有以下內置屬性:
code
name
description
作用如圖: