宏
是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
看做一個整體。