1. 程式人生 > >Flask-Jinja2模板學習總結

Flask-Jinja2模板學習總結

1. 變數

表示方法 {{ name }} ,支援所有資料型別;過濾變數的方法是載入過濾器 {{ name | filter }},過濾器有系統的和自定義的。

I. 系統的為標準過濾器:

a. 字串操作

{# 當變數未定義時,顯示預設字串,可以縮寫為d #}
<p>{{ name | default('No name', true) }}</p>

{# 單詞首字母大寫 #}
<p>{{ 'hello' | capitalize }}</p>

{# 單詞全小寫 #}
<p>{{ 'XML' | lower }}</p>

{# 去除字串前後的空白字元 #}
<p>{{ ' hello ' | trim }}</p>

{# 字串反轉,返回"olleh" #}
<p>{{ 'hello' | reverse }}</p>

{# 格式化輸出,返回"Number is 2" #}
<p>{{ '%s is %d' | format("Number", 2) }}</p>

{# 關閉HTML自動轉義 #}
<p>{{ '<em>name</em>' | safe }}</p>

{% autoescape false %}
{# HTML轉義,即使autoescape關了也轉義,可以縮寫為e #}
<p>{{ '<em>name</em>' | escape }}</p>
{% endautoescape %}

b. 數值操作

{# 四捨五入取整,返回13.0 #}
<p>{{ 12.8888 | round }}</p>

{# 向下擷取到小數點後2位,返回12.88 #}
<p>{{ 12.8888 | round(2, 'floor') }}</p>

{# 絕對值,返回12 #}
<p>{{ -12 | abs }}</p>

c. 列表操作

{# 取第一個元素 #}
<p>{{ [1,2,3,4,5] | first }}</p>

{# 取最後一個元素 #}
<p>{{ [1,2,3,4,5] | last }}</p>

{# 返回列表長度,可以寫為count #}
<p>{{ [1,2,3,4,5] | length }}</p>

{# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p>

{# 列表排序,預設為升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p>

{# 合併為字串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(' | ') }}</p>

{# 列表中所有元素都全大寫。這裡可以用upper,lower,但capitalize無效 #}
<p>{{ ['tom','bob','ada'] | upper }}</p>

d. 字典列表操作

{% set users=[{'name':'Tom','gender':'M','age':20},
{'name':'John','gender':'M','age':18},
{'name':'Mary','gender':'F','age':24},
{'name':'Bob','gender':'M','age':31},
{'name':'Lisa','gender':'F','age':19}]
%}


{# 按指定欄位排序,這裡設reverse為true使其按降序排 #}
<ul>
{% for user in users | sort(attribute='age', reverse=true) %}
<li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>

{# 列表分組,每組是一個子列表,組名就是分組項的值 #}
<ul>
{% for group in users|groupby('gender') %}
<li>{{ group.grouper }}<ul>
{% for user in group.list %}
<li>{{ user.name }}</li>
{% endfor %}</ul></li>
{% endfor %}
</ul>

{# 取字典中的某一項組成列表,再將其連線起來 #}
<p>{{ users | map(attribute='name') | join(', ') }}</p>

e. Flask內建過濾器

Flask提供了一個內建過濾器”tojson”,它的作用是將變數輸出為JSON字串。這個在配合Javascript使用時非常有用。
<script type="text/javascript">
var users = {{ users | tojson | safe }};
console.log(users[0].name);
</script>
注意,這裡要避免HTML自動轉義,所以加上safe過濾器。

II. 語句塊過濾

Jinja2還可以對整塊的語句使用過濾器。
{% filter upper %}
This is a Flask Jinja2 introduction.
{% endfilter %}

III. 自定義過濾器

def double_step_filter(l):
    return l[::2]
app.add_template_filter(double_step_filter, 'double_step')
#另外一種方式
@app.app_template_filter('double_step')
def double_step_filter(l):
    return l[::2]
兩種方式均可自定義過濾器,定義後可以直接在模板中使用。

2. 控制結構

條件控制

if...else...endif

判斷條件是否符合,並執行相應的語句

迴圈

for...endfor
用於渲染一組元素

巨集

macro...endmacro
類似函式
定義一個巨集,指定巨集的名稱、引數,呼叫
{% macro x(y) %}
    ...
{% endmacro %}

{{ x(y) }}
如果需要在多個模板中複用,可以將巨集的定義放入一個檔案,‘macro.html’,然後匯入使用
import 'macro.html' as macro

{{ macro.x(y) }}

繼承

如果多個頁面的大部分內容相同,可以定義一個母模板,包含相同的內容,然後子模板繼承內容,並根據需要進行部分修改base.html,母模板,其中,用{% block title %}...{% endblock %}定義了可以由子模板替換的區域,title是區塊的名稱,可以有多個區塊。
在子模板中,宣告繼承的母模板,然後用{% block title %}...{% endblock %}指定替換哪個區塊的內容,並填入自己的內容。子模板中沒有指定的區塊,預設使用母模板的內容
{% extends "base.html" %}

{% block title %}john{% endblock %}
如果希望能夠保留母版的內容,並新增新內容,可以使用super()
{% extends "base.html" %}

{% block title %}
    {{ super() }}
    john
{% endblock %}
模板裡面,不能同時有兩個{% extends " " %}語句,即使另一個被註釋了也不行

包含

如果多個網頁中都有一段內容相同,可以將相同的內容放入一個檔案中comments.html,通過include匯入
{% include 'comments.html' %}

3. 自定義錯誤頁面

像常規路由一樣,Flask 允許程式使用基於模板的自定義錯誤頁面。最常見的錯誤程式碼有兩個:404,客戶端請求未知頁面或路由時顯示;500,有未處理的異常時顯示。
@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

4. 標準上下文

下面全域性變數預設在 Jinja2 模版中可用:

config

當前配置物件 (flask.config)
New in version 0.6.
Changed in version 0.10: 現在一直可用,即使是匯入的模版。

request

當前請求物件 (flask.request)

session

當前會話物件 (flask.session)

g

實現全域性變數的請求範圍的物件 (flask.g)

url_for()

flask.url_for() 函式。

get_flashed_messages()

flask.get_flashed_messages() 函式。

5. 上下文處理器

Flask 中的上下文處理器自動向模板的上下文中插入新變數。上下文處理器在模板 渲染之前執行,並且可以在模板上下文中插入新值。上下文處理器是一個返回字典的函式。 這個字典的鍵值將與應用中的所有模板上下文結合:
@app.context_processor
def inject_user():
    return dict(user=g.user)
變數不僅限於值;一個上下文處理器也可以使函式在模板中可用(由於 Python 允許傳遞函式):
@app.context_processor
def utility_processor():
    def format_price(amount, currency=u'€'):
        return u'{0:.2f}{1}.format(amount, currency)
    return dict(format_price=format_price)
上面的上下文處理器使得 format_price 函式在所有模板中可用:
{{ format_price(0.33) }}