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()
来源: https://www.cnblogs.com/why957/p/9123248.html