Flask入门之模板导入与块宏(六)
1 模板包含include
主体结构(导入整个模板,直接渲染不可修改)
{% include('模板名称') %}
{% include('目录/模板名称') %}
功能: 其功能就是将另一个模板加载到当前模板中,并直接渲染在当前位置上,而且是一次渲染整个模块内容
#导入头部header.html {% include 'header.html' %} 主体内容 #导入底部footer.html {% include 'footer.html' %} #忽略模板文件不存在时的错误 {% include 'footer.html' ignore missing %} #也可以组成模板列表,会按照顺序依次加载 {% include ['footer.html','bottom.html','end.html'] ignore missing %}
注意:当include模板文件不存在时,程序会抛出异常,加上ignore missing关键字可以忽略不存在时的异常.
2 宏(macro)
概念 : Jinja2中宏的功能类似python中函数定义,分为声明与调用两个部分
(1) 宏的定义
主体结构
{% macro 宏的名称([参数...s]) %}
宏的主体
{% endmacro %}
宏的调用
{{ 宏的名称[参数列表] }}
(2) 宏的实例1
templates/common/formmacro.html
{% macro input(type='text',name='',value='') %} <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> {% endmacro %}
先导入后调用
{% import 'common/formmacro.html' as formmacro %} <form action=''> <p>用户名:{{ formmacro.input(name='uername') }}</p> <p>密码:{{ formmacro.input('password','userpass') }}</p> <p>性别: {{ formmacro.input('radio','sex',1) }} 男 {{ formmacro.input('radio','sex',0) }} 女 </p> <p>{{ formmacro.input('submit',value='submit') }}</p> </form>
(3) 宏的实例2
#定义一个users宏,输出user.name caller(user.gender)传递参数 {% macro list_users(users) -%} <table> {%- for user in users %} <tr><td>{{ user.name |e }}</td>{{ caller(user.gender) }}</tr> {%- endfor %} </table> {%- endmacro %} #调用宏,{{ caller(user.gender) }}”部分被调用者”{% call(gender) %}”语句块内部的内容替代 {% call(gender) list_users(users) %} <td> {% if gender == 'M' %} <img src="{{ url_for('static', filename='img/male.png') }}" width="20px"> {% else %} <img src="{{ url_for('static', filename='img/female.png') }}" width="20px"> {% endif %} </td> <td><input name="delete" type="button" value="Delete"></td> {% endcall %}
(4)import 导入:(针对导入宏或者自定义的宏)
import ....as....
{% import 'common/formmacro.html' as formmacro %} 如果index.html和formmacro同级 可以直接导入 {% import 'formmacro.html' as formmacro %}
from ... import as
{% from 'common/formmacro.html' import input %} #从包导入宏 {% from 'common/formmacro.html' import input as form %} #从包导入宏并重命名
注意:
- 不能在宏定义的上方去调用
- 宏如果存在形参 如果不传实参 则行参的值为空 也不会报错
- 在给形参默认值的时候 必须遵循默认值的规则 幽默认值的放在后面 和 python的函数一样
(5) 宏的内部变量
varargs : 这是一个列表。如果调用宏时传入的参数多于宏声明时的参数,多出来的没指定参数名的参数就会保存在这个列表中。
kwargs : 这是一个字典。如果调用宏时传入的参数多于宏声明时的参数,多出来的指定了参数名的参数就会保存在这个字典中。
{% macro input(name, type='text', value='') %} <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}"> <br /> {{ varargs }} <br /> {{ kwargs }} {% endmacro %} <p>{{ input('submit', 'submit', 'Submit', 'more arg1', 'more arg2', ext='more arg3') }}</p>
3 块(block)
主体结构:一般结合继承使用,用于填充block块
{% extend ‘parent.html’ %} {% block block_name %} {% endblock 块名%}
注意:
- 模板不支持多继承,也就是子模板中定义的块,不可能同时被两个父模板替换。
- 模板中不能定义多个同名的块,子模板和父模板都不行,这样无法知道要替换哪一个部分的内容。
(1) 保留父模板中的内容采用 super( )方法
python #父模板中设置好块 <head> {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <title>{% block title %}{% endblock %}</title> {% endblock head%} </head> <body> <div class="page"> {% block content %} {% endblock %} </div> </body>
python {% block title %}首页{% endblock %} {% block head %} {{ super() }} #继承父类保持父类不变 <style type="text/css"> h1 { color: #336699; } </style> {% endblock %}
注: 父模板与子模板中都有head块,运行时,父模板中的块先被加载,而后是子模板的块head
(2) 块内语句的作用域
默认情况下,块内语句是无法访问块作用域外的变量
#父模板中 {% for item in range(5) %} <li>{% block list %}{% endblock %}</li> {% endfor %} #子模板继承 {% block list %} <p>{{ item }}</p> {% endblock %} #此时子模板是无法获取到父模板中 list块中的内容,即打印为空
如果你想在块内访问这个块外的变量,你就需要在块声明时添加scoped
关键字
#父模板中添加 scoped 关键字 {% for item in range(5) %} <li>{% block list scoped %}{% endblock %}</li> {% endfor %} #子模板继承 {% block list %} <p>{{ item }}</p> {% endblock %} #此时item能获取到 0,1,2,3,4
4 模板的继承
主体架构
{% extends '继承的模板名称' %}
{% block 替换的名称 %}
{% endblock %}
自定义一个基类模板base.html
<!DOCTYPE html> <html lang="en"> {% block head %} <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> #title块 {% block meta %}{% endblock %} <style> {% block style %} #css样式块 *{color:red;} {% endblock %} </style> {% block link %}{% endblock %} #外联样式块 </head> {% endblock %} <body> {% include 'common/header.html' %} #页面导入 {% block content %} {% endblock %} {% include 'common/footer.html' %} #页面导入 </body> </html>
使用index.html继承父类
{% extends 'common/base.html' %} #继承父类模板 {% block title %}首页{% endblock %} {% block style %} {# 调用基础模板内的样式 如果不调用则全部被覆盖 #} {{ super() }} p{font-size:20px;} {% endblock %} {% block content %} 我是中间的内容部分 {% endblock %}
注意:
- 在替换的外部的填写的内容 不会被显示出来
- 如果在替换某一个block的时候 替换以后所有的样式消失 则去查看是否有调用super()