使用flask的render_template(渲染HTML模板)創建一個簡單的web程序,代碼如下:
#coding:utf-8
from flask import Flask
from flask import render_template
app=Flask(__name__)
@app.route('/')
def f():
comments=['nihao','jing']
return render_template('if.html',comments=comments)
if __name__=='__main__':
app.run()
HTML模板if.html如下:
<ul>
{% for comment in comments %}
<li>{{ comment }}</li>
{% endfor %}
</ul>
運行結果如圖:
接下來用宏定義重新寫HTML模板,宏定義forms.html如下:
{% macro t(comment) %}
<li>{{comment}}</li>
{% endmacro %}
在另一模板t_if.html中引用該宏定義:
{% import 'forms.html' as forms %} <!--將forms導入,as後面的名字可以隨意定義-->
<ul>
{% for comment in comments %}
{{forms.t(comment)}} <!--引用其中的宏定義-->
{% endfor %}
</ul>
運行後與上面效果相同。
雖然程序可以工作,但不理解宏定義究竟如何工作的,比如
{% macro t(comment) %}
括號裏面的參數有何規定和要求,主程序中的comments是如何傳到模板的等等,但搜了一下,發現大部分都是互相copy,並無深入介紹,so,自己動手豐衣足食。
首先,先試驗一下將
{% macro t(comment) %}
括號去掉,因爲受到c裏面define的影響,直覺上覺得用一個字母t代替下面的語句沒問題,試驗以後發現報錯,
看來缺了括號不行,那就加上括號,改爲:
{% macro t() %} 注意此時括號沒有參數
運行結果如下:
雖然沒報錯,但列表裏的內容顯示不出來了。我們分析,既然有兩個點,說明執行到了t_if.html中
{{forms.t()}}這一步,只不過沒有內容沒顯示出來罷了。於是猜測
% macro t(comment) %}
括號中的comment是用來傳參的,再將t_if.html的{% for comment in comments %}
{{forms.t(comment)}} <!--引用其中的宏定義-->
{% endfor %}
改爲
{% for c in comments %}
{{forms.t(c)}} <!--引用其中的宏定義-->
{% endfor %}
相應的forms.html也改爲{% macro t(c) %}
<li>{{c}}</li>
{% endmacro %}
可正常運行。
於是我們得出結論,jinja2 中的宏定義不能隨便定義,如果裏面有可變參數,需要用小括號將參數傳遞進去。