flask 考虑到模板代码的重用性,Jiaja2提供了块 (Block)和宏 (Macro)来提高代码的继承和复用性。其中块 (Block)的使用可以极大精简代码,可以通过继承(extend)扩展让大量代码重复使用,并在Block自由定制替换内容块;而宏 (Macro) 的使用更可以极大的提高模板的复用性,减少复杂度,类似于函数,可以传入参数。这篇我们就来学习下 块 (Block)和宏 (Macro)的用法。
块 (Block)
关于模板的继承,我们可以在子模板的顶部使用如”{% extend ‘base.html’ %}”语句来声明继承。而子模板中由”{% block block_name %}”和”{% endblock %}”所包括的语句块,将会替换父模板中同样由”{% block block_name %}”和”{% endblock %}”所包括的语句块。
这就是块的功能,模板语句的替换。这里要注意几个点:
- 模板不支持多继承,也就是子模板中定义的块,不可能同时替换两个父模板的块。
- 模板中不能定义同名的块,因为这样无法确认替换块的内容。
建议在”endblock”关键字后也加上块名,比如”{% endblock block_name %}”,增加可读性。
使用父模板块 (Block)的内容
如果子模板想使用父模板中的块里的内容,请使用{
{ super() }}
。请看下面例子:
<!doctype html>
<head>
{% block head %}
<link rel="stylesheet" href="{
{ url_for('static', filename='style.css') }}">
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
<div class="page">
{% block body %}
{% endblock %}
</div>
</body>
上面是父模板,我要在子模板里使用”head”块的css文件并增加新的文件,如下:
{% block title %}Block Sample{% endblock %}
{% block head %}
{
{ super() }}
<style type="text/css">
h1 { color: #336699; }
</style>
{% endblock %}
父模板同子模板的”head”块中都有内容。程序运行后,父模板中的”head”块语句先被加载,而后加载子模板中的”head”块语句。
块内语句的作用域
默认情况下,块内语句是无法访问块外作用域中的变量。比如:
{% for item in range(5) %}
<li>{% block loop_item %}{
{ item }}{% endblock %}</li>
{% endfor %}
模板中定义”list”块并访问循环中的”item”变量:
这个例子会输出空的 < li> 项,因为 item 在块中是不可用的。其原因是,如果 块被子模板替换,变量在其块中可能是未定义的或未被传递到上下文。
从 Jinja 2.2 开始,你可以显式地指定在块中可用的变量,只需在块声明中添加 scoped 修饰,就把块设定到作用域中:
{% for item in range(5) %}
<li>{% block loop_item scoped %}{
{ item }}{% endblock %}</li>
{%