flask第30篇——宏macro和import标签
宏
是Jinja2
特有的,像Django
则没有这个。
先新建一个项目macroDemo
:
然后在templates
文件夹中新建index.html
文件,并在代码中返回渲染后的文件:
然后回到index.html
,现在假设我们要写一个登录的表单:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td><input type="text" placeholder="请输入账号"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" placeholder="请输入密码"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</tbody>
</table>
</body>
</html>
执行app.py
文件,看到:
看一下刚才写的index.html
文件,每个标签都传了如type
,placeholder
等属性,那么我们可不可以把相同的内容提取出来呢?答案当然是可以,这时候就要用到宏的概念。
-
定义宏
{% macro 名称() %}
代码块
{% endmacro %}
-
调用
{{ 宏名称() }}
-
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
{% macro input() %}
<input type="text">
{% endmacro %}
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td>{{ input() }}</td>
</tr>
<tr>
<td>密码</td>
<td>{{ input() }}</td>
</tr>
<tr>
<td></td>
<td>{{ input() }}</td>
</tr>
</tbody>
</table>
</body>
</html>
保存一下,刷新页面看到:
也就是说代码已经生效了。其实可以把宏的名称()
看成一个函数。
但是现在input
标签中还有type
、placeholder
等属性,这个时候就需要给input()
传参数了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
{% macro input(type, name, placeholder, value) %}
<input type="{{ type }}", name="{{ name }}", placeholder="{{ placeholder }}", value="{{ value }}">
{% endmacro %}
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td>{{ input("text", "", "请输入账号", "") }}</td>
</tr>
<tr>
<td>密码</td>
<td>{{ input("text", "", "请输入密码", "") }}</td>
</tr>
<tr>
<td></td>
<td>{{ input("submit", "", "", "提交") }}</td>
</tr>
</tbody>
</table>
</body>
</html>
保存,然后看到页面:
当然,下面在传值的时候也可以用关键字参数进行传递,比如
{{ input(type="submit", name="", placeholder="", value="提交") }}
效果是一样的。
如果属性有默认值,那么也可以添加默认值:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
{% macro input(type='text', name='', placeholder='', value='') %}
<input type="{{ type }}", name="{{ name }}", placeholder="{{ placeholder }}", value="{{ value }}">
{% endmacro %}
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td>{{ input(placeholder="请输入账号") }}</td>
</tr>
<tr>
<td>密码</td>
<td>{{ input(placeholder="请输入密码") }}</td>
</tr>
<tr>
<td></td>
<td>{{ input(type="submit", value="提交") }}</td>
</tr>
</tbody>
</table>
</body>
</html>
需要注意的是如果给了默认值,那么传参的时候就必须用关键字参数
进行传值了。
也可以将宏封装成一个包的形式,在需要使用的时候通过导入进行调用:
我们在template
文件夹下新建文件夹macros
专门存放宏文件,并在该文件夹中新建forms.html
文件。将宏的定义从index.html
文件中剪切出来,放到forms.html
文件中:
{% macro input(type='text', name='', placeholder='', value='') %}
<input type="{{ type }}", name="{{ name }}", placeholder="{{ placeholder }}", value="{{ value }}">
{% endmacro %}
然后在index.html
中只需要导入宏文件即可。导入方法:{% import 'macros/forms.html' as forms %}
注意,这里后面必须要as
,也就是必须给导入的文件起个名字。
代码:
{% import 'macros/forms.html' as forms %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td>{{ forms.input(placeholder="请输入账号") }}</td>
</tr>
<tr>
<td>密码</td>
<td>{{ forms.input(placeholder="请输入密码") }}</td>
</tr>
<tr>
<td></td>
<td>{{ forms.input(type="submit", value="提交") }}</td>
</tr>
</tbody>
</table>
</body>
</html>
保存以后回到页面,可以看到效果不变。
现在forms.html
文件中只有一个宏定义,如果是多个的时候,比如把froms.html
改为:
{% macro input(type='text', name='', placeholder='', value='') %}
<input type="{{ type }}", name="{{ name }}", placeholder="{{ placeholder }}", value="{{ value }}">
{% endmacro %}
{% macro textarea(name="", cols="", rows="") %}
<textarea name="{{ name }}", cols="{{ cols }}", rows="{{ rows }}"></textarea>
{% endmacro %}
这时候在index.html
导入就要用:{% from 'macros/forms.html' import input %}
或者{% from 'macros/forms.html' import input as input_field%}
代码:
{% from 'macros/forms.html' import input %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
</head>
<body>
<table>
<tbody>
<tr>
<td>账号</td>
<td>{{ input(placeholder="请输入账号") }}</td>
</tr>
<tr>
<td>密码</td>
<td>{{ input(placeholder="请输入密码") }}</td>
</tr>
<tr>
<td></td>
<td>{{ input(type="submit", value="提交") }}</td>
</tr>
</tbody>
</table>
</body>
</html>
执行以后页面显示效果不变。如果现在要把两个宏都导入,那就只需要:
{% from 'macros/forms.html' import input, textarea %}
或者{% from 'macros/forms.html' import input as input_field, textarea%}
如果用下面这种方式,就要把input as input_field
看做一个整体。