dict()函數,方便生成字典型變量html
{% set user = dict(name='Mike',age=15) %} <p>{{ user | tojson | safe }}</p> {# 顯示 '{"age": 15, "name": "Mike"}' #}
joiner()函數,神奇的輔助函數。它能夠初始化爲一個分隔符,而後第一次調用時返回空字符串,之後再調用則返回分隔符。對分隔循環中的內容頗有幫助json
{% set sep = joiner("|") %} {% for val in range(5) %} {{ sep() }} <span>{{ val }}</span> {% endfor %} {# 顯示 "0 | 1 | 2 | 3 | 4" #}
cycler()函數,在給定的序列中輪循,列表項<li>的」class」在」odd」和」even」兩個值間輪循app
{% set cycle = cycler('odd', 'even') %} <ul> {% for num in range(10, 20, 2) %} <li class="{{ cycle.next() }}">Number is "{{ num }}", next line is "{{ cycle.current }}" line.</li> {% endfor %} </ul>
「cycler()」函數返回的對象能夠作以下操做函數
將Flask應用代碼中定義的函數,經過」add_template_global」將其傳入模板便可url
import re def accept_pattern(pattern_str): pattern = re.compile(pattern_str, re.S) def search(content): return pattern.findall(content) return dict(search=search, current_pattern=pattern_str) app.add_template_global(accept_pattern, 'accept_pattern')
上例中的accept_pattern函數會先預編譯一個正則,而後返回的字典中包含一個查詢函數」search」,以後調用」search」函數就能夠用編譯好的正則來搜索內容了。」app.add_template_global」方法的第一個參數是自定義的全局函數,第二個是全局函數名稱。如今,讓咱們在模板中使用」accept_pattern」全局函數:spa
{% with pattern = accept_pattern("<li>(.*?)</li>") %} {% set founds = pattern.search("<li>Tom</li><li>Bob</li>") %} <ul> {% for item in founds %} <li>Found: {{ item }}</li> {% endfor %} </ul> <p>Current Pattern: {{ pattern.current_pattern }}</p> {% endwith %}
「Tom」和」Bob」被抽取出來了code
Flask一樣提供了添加全局函數的裝飾器」template_global」,以方便全局函數的添加。咱們來用它將取系統當前時間的函數」current_time」定義爲全局函數。orm
import time @app.template_global('end_with') def current_time(timeFormat="%b %d, %Y - %H:%M:%S"): return time.strftime(timeFormat)
<p>Current Time is: {{ current_time() }}</p> <p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>
Flask添加全局函數的方法是封裝了對Jinja2環境變量的操做。上述添加」current_time」全局函數的方法,等同於下面的代碼。htm
app.jinja_env.globals['current_time'] = current_time
{% macro input(name, type='text', value='') -%} <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}"> {%- endmacro %}
<p>{{ input('username', value='user') }}</p> <p>{{ input('password', 'password') }}</p> <p>{{ input('submit', 'submit', 'Submit') }}</p>
先來建立個宏」list_users」:對象
{% macro list_users(users) -%} <table> <tr><th>Name</th><th>Action</th></tr> {%- for user in users %} <tr><td>{{ user.name |e }}</td>{{ caller() }}</tr> {%- endfor %} </table> {%- endmacro %}
調用者的代碼:
{% set users=[{'name':'Tom','gender':'M','age':20}, {'name':'John','gender':'M','age':18}, {'name':'Mary','gender':'F','age':24}] %} {% call list_users(users) %} <td><input name="delete" type="button" value="Delete"></td> {% endcall %}
與上例不一樣,這裏咱們使用了」{% call %}」語句塊來調用宏,語句塊中包括了一段生成」Delete」按鈕的代碼。運行下試試,你會發現每一個用戶名後面都出現了」Delete」按鈕,也就是」{{ caller( ) }}」部分被調用者」{% call %}」語句塊內部的內容替代了,我的以爲,主要是有些時候HTML語句太複雜(如上例),不方便寫在調用參數上,因此就寫在」{% call %}」語句塊裏了。
Jinja2的宏不但能訪問調用者語句塊的內容,還能給調用者傳遞參數
首先,咱們將表格增長一列性別,並在宏裏調用」caller()」方法時,傳入一個變量」user.gender」:
{% macro list_users(users) -%} <table> <tr><th>Name</th><th>Gender</th><th>Action</th></tr> {%- for user in users %} <tr><td>{{ user.name |e }}</td>{{ caller(user.gender) }}</tr> {%- endfor %} </table> {%- endmacro %}
修改下調用者語句塊:
{% call(gender) list_users(users) %} <td> {% if gender == 'M' %} <img src="{{ url_for('static', filename='img/male.png') }}" width="20px"> {% else %} <img src="{{ url_for('static', filename='img/female.png') }}" width="20px"> {% endif %} </td> <td><input name="delete" type="button" value="Delete"></td> {% endcall %}
咱們在使用」{% call %}」語句時,將其改成了」{% call(gender) … %}」,這個括號中的」gender」就是用來接受宏裏傳來的」user.gender」變量。所以咱們就能夠在」{% call %}」語句中使用這個」gender」變量來判斷用戶性別。這樣宏就成功地向調用者傳遞了參數。
宏的內部可使用」caller( )」方法獲取調用者的內容。此外宏還提供了兩個內部變量:
varargs
這是一個列表。若是調用宏時傳入的參數多於宏聲明時的參數,多出來的沒指定參數名的參數就會保存在這個列表中。
kwargs
這是一個字典。若是調用宏時傳入的參數多於宏聲明時的參數,多出來的指定了參數名的參數就會保存在這個字典中。
{% macro input(name, type='text', value='') -%} <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}"> <br /> {{ varargs }} <br /> {{ kwargs }} {%- endmacro %} <p>{{ input('submit', 'submit', 'Submit', 'more arg1', 'more arg2', ext='more arg3') }}</p>
能夠看到,varargs變量存了參數列表」[‘more arg1’, ‘more arg2’]」,而kwargs字典存了參數」{‘ext’:’more arg3′}」。
當」include」的模板文件不存在時,程序會拋出異常。你能夠加上」ignore missing」關鍵字,這樣若是模板不存在,就會忽略這段」{% include %}」語句。
{% include 'footer.html' ignore missing %}
{% include ['footer.html','bottom.html','end.html'] ignore missing %}
上例中,程序會按順序尋找模板文件,第一個被找到的模板即被加載,而其後的模板都會被忽略。若是都沒找到,那整個語句都會被忽略。