使用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 中的宏定义不能随便定义,如果里面有可变参数,需要用小括号将参数传递进去。