模板可以理解为一个特殊的html文件,特殊之处就在于这个html文件包含固定内容和动态部分,其动态部分可以借助模板引擎进行传参,类似于django
1.模板引擎传参
app.py
class Girl:
def __init__(self,name):
self.name = name
self.age = 18
self.gender = '女'
def __str__(self):
return self.name
@app.route('/show')
def show():
name = 'zz'
age = 18
hobby = ['c','t1','r1','l']
dict1 = {'gift':'礼物','gift1':'礼物1','gift2':'礼物2',}
girl_1 = Girl('zz')
return render_template("show.html",name = name,age = age,hobby = hobby,gift = dict1,girl = girl_1)
show.html
<body>
<div>展示</div>
{# 变量显示 由传递时的key决定 #}
<p>
用户:{{ name }} 年龄:{{ age }}
<br>
hobby:{{ hobby.0 }} {{ hobby[1] }}
<br>
gift: {{ gift.gift }} {{ gift.get('gift1') }}
<br>
girl: {{ girl.age }}
</p>
2.if/for语句
<head>
<meta charset="UTF-8">
<title>信息显示</title>
<style>
.a{
color: #ff0000;
font-weight:bold;
}
</style>
</head>
<body>
{# 注释 此时只是对后端不可见,直接用浏览器打开可看见 #}
<!-- 注释 直接用浏览器打开也不可看见 -->
{# for #}
<ul>
{% for ho in hobby %}
<li>{{ ho }}</li>
{% endfor %}
</ul>
{# 反向输出for #}
<ul>
{% for ho in hobby | reverse%}
<li>{{ ho }}</li>
{% endfor %}
</ul>
{# if #}
<ul>
{% for ho in hobby %}
{% if ho|length >1 %}
<li class="a">{{ ho }}</li>
{% else %}
<li>{{ ho }}</li>
{% endif %}
{% endfor %}
</ul>
</body>
3.根据个数动态创建标签
@app.route('/show')
def show():
users = [
{'username': 'zz', 'password': '123', 'phone': '135********'},
{'username': 'zz1', 'password': '1231', 'phone': '135*******1'},
{'username': 'zz2', 'password': '1232', 'phone': '135*******2'},
{'username': 'zz3', 'password': '1233', 'phone': '135*******3'},
{'username': 'zz4', 'password': '1234', 'phone': '135*******4'},
]
return render_template("show.html",users=users)
<table border="1" width="80%" cellspacing="0">
{% for user in users %}
<tr>
<td>{{ loop.index }}</td>
{# index:从1开始 index0:从0开始 revindex:从length开始 #}
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
将第一个背景设置为灰色
<table border="1" width="80%" cellspacing="0">
{% for user in users %}
{% if loop.first %}
{# 如果为第一个 #}
<tr style="background-color: darkgrey">
<td>{{ loop.index }}</td>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.phone }}</td>
</tr>
{% else %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endif %}
{% endfor %}
或
<table border="1" width="80%" cellspacing="0">
{% for user in users %}
{# 如果为第一个 #}
<tr {% if loop.first %}style="background-color: darkgrey{% endif %}">
{# <tr {% if loop.index==3 %}style="background-color: darkgrey{% endif %}"> #}
<td>{{ loop.index }}</td>
{# index:从1开始 index0:从0开始 revindex:从length开始#}
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
4.过滤器
本质为函数,{{变量名|过滤器(*args)}}
常见的过滤器:
字符串:
1.safe 禁用转义
2.capitalize 首字母大写
3.lower/upper 全小写/全大写
4.title 一句话中每个单词首字母大写
5.reverse 翻转
6.format 格式化
7.truncate 截断
列表:
1.length 显示长度
2.first/last
3.sum 对于整型的计算
4.sort 排序
app
@app.route('/show')
def show():
users = [
{'username': 'zz', 'password': '123', 'phone': '135********'},
{'username': 'zz1', 'password': '1231', 'phone': '135*******1'},
{'username': 'zz2', 'password': '1232', 'phone': '135*******2'},
{'username': 'zz3', 'password': '1233', 'phone': '135*******3'},
{'username': 'zz4', 'password': '1234', 'phone': '135*******4'},
]
return render_template("show.html",users=users,string1='<h1>hai</h1>',string2 ='hello')
<body>
{# 某些函数在模板语言里不可用,所以要依赖于过滤函数 {{ users.len()}} #}
当前用户共{{ users|length }}人
{#{% for user in users.0.values() %}#}
{% for user in users.0.items() %}
<p>{{ user }}</p>
{% endfor %}
<br>
{# 过滤器转义 后台传入带标签的字符串 第一句显示<h1>hai</h1>,后一句显示大写加粗的hai#}
{{ string1 }}
{{ string1|safe }}
<br>
{# 首字母大写 #}
{{ string2|capitalize}}
<br>
{# 格式化 #}
{{ 'you say %s,%d'|format(string2,18) }}
<br>
{# HELL...一共为7个字符,后三位为... #}
{{ 'helloworld'|truncate(7,leeway=0)|upper }}
</body>
5.自定义过滤器
1.使用flask中的add_template_filter
2.使用装饰器实现
@app.route('/show')
def show():
msg='hello world'
li =[5,8,9,6,4]
return render_template("show.html",msg=msg,li=li)
# add_template_filter
def replace_hello(value):
print('---->',value)
value = value.replace('hello','').strip()
print('====>',value)
return value
app.add_template_filter(replace_hello,'replace') # replace为调用的名字
# 装饰器
@app.template_filter('li_re') # 调用的名字
def reverse_list(li):
temp_li=list(li)
temp_li.reverse()
return temp_li
<body>
{{ msg|replace }}
<hr>
{{ li }}
<hr>
{{ li|li_re }}
</body>
6.模板继承
同https://blog.csdn.net/weixin_49722641/article/details/109472458
模板挖坑:
{% block 名字 %}
{% endblock %}
子填坑:
{% extends "*.html" %}
{% block 名字 %}
改的内容
{% endblock %}
若想在子类里改变样式,必须在父模板中预留位置{% block 名字 %} {% endblock %}
,然后再其内进行填充。
对于静态文件的引用使用url_for先寻找static的url再拼接文件目录<link rel="stylesheet" href="{{ url_for('static',filename='css/style.css') }}">
此时路径变为href="/static/css/style.css"
{% include'*/*/*.html'% }
表示将星目录下的*.html文件导入到该页面中,适用场景:ABC页面包含相同的部分,但是其他页面不包含,所以不可用模板,用include,定义一个共用部分的文件,其余用到的直接根据路径引用即可
7.宏:macro
可看为jinja2的一个函数,可返回一个HTML字符串。目的:避免代码冗余,使之复用。
将宏写入template的macro中,此次新建html为macro
{# def func(a,b=8): 类似 #}
{# 定义宏 #}
{% macro form(action,value='登录',method="post") %}
<form action="{{ action }}" method="{{ method }}">
<input type="text" placeholder="用户名" name="username">
<br>
<input type="password" placeholder="密码" name="password">
<br>
<input type="submit" value="{{ value }}">
</form>
{% endmacro %}
{# 本文件内调用宏 #}
{{ form('/') }}
其余文件调用宏
<body>
{# 别的文件调用 #}
{% import 'macro/macro.html' as f %}
{{ f.form('/',value = '注册') }}
</body>
app
@app.route('/show', methods=['post','get'])
def show():
return render_template("show.html")
@app.route('/', methods=['post','get'])
def index():
return 'hello'