类似于python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余。
Jinja2支持宏,还可以导入宏,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复。
1.定义一个 input()的宏
{% macro input() %}
<input type="text" name="username" value="" size="30"/>
{% endmacro %}
2.在模板中调用input()宏
{{ input() }}
这样的宏没有参数的传入,下面再来看看如何设置带参数的宏。
1.定义带参数的宏
{% macro input(name,value='',type='text',size=20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}"/>
{% endmacro %}
2.调用宏,并传递参数
{{ input(value='name',type='password',size=40)}}
1.编写macro_ex.html模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>无参数的宏</p>
{% macro input1() %}
<input type="text" name="username" value="" size="30"/>
{% endmacro %}
{{ input1() }}
<p>设置带参数的宏</p>
{% macro input2(name,value='',type='text',size=20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}"/>
{% endmacro %}
{{ input2(value='name',type='password',size=40) }}
</body>
</html>
2.编写一个视图函数
from flask import Flask, render_template
app = Flask(__name__)
app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"
@app.route("/macro_ex", methods=["GET", "POST"])
def macro_ex():
return render_template("macro_ex.html")
if __name__ == '__main__':
app.run(debug=True)
3.访问视图查看效果访问 http://127.0.0.1:5000/macro_ex

可以看到只需要调用模板的宏就可以直接创建一个input,如果宏的html比较复杂,那么就可以更加方便,减少html的编写。
下面还有更加方便的做法。
在python中的公共类方法可以写到一个公共工具类中,后续方便其他地方调用。而模板宏也可以有同样的做法。
可以将模板宏都写到一个html文件中,然后通过模板继承的方式提供调用,下面来看看怎么操作。
创建文件名可以自定义macro.html
{% macro login_form() %}
<input type="text" name="username" placeholde="Username">
<input type="password" name="password" placeholde="Password">
<input type="submit">
{% endmacro %}
在其它模板文件中先导入,再调用
{% import 'macro.html' as macro_import %}
{{ macro_import.login_form() }}
完整示例如下:1.创建macro.html文件

2.编写另一个html文件macro_ex.html,用来导入模板宏以及调用

可以看到有了宏的使用,已经很方便避免重复编写的html内容。下面再来介绍Django模板也有的继承功能。
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
{% block top %}{% endblock %}标签定义的内容,相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。
子模板使用extends指令声明这个模板继承自哪?父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()。
{% block top %}
顶部菜单
{% endblock top %}
{% block content %}
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}
{% extends 'base.html' %}
{% block content %}
需要填充的内容
{% endblock content %}
模板继承使用时注意点:
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。它的功能是将另一个模板整个加载到当前模板中,并直接渲染。
{% include 'index.html' %}
{% include 'index.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上ignore missing关键字。如果包含的模板文件不存在,会忽略这条include语句。
注意:include可以多次使用,也就是可以多次加载模板内容到当前模板中。
设置include一个不存在的模板,如下:
{% include 'hello.html' %}
上面说到,如果包含的模板文件不存在,则会抛出异常TemplateNotFound,如下:

如果想要避免报错,可以增加关键字ignore missing,如下:
{% include 'hello.html' ignore missing%}
再次访问页面则不会报错了,直接显示空白而已,如下:
