Jinja 是一种快速的、富有表现力的、可扩展的模板引擎。模板中的特殊占位符允许编写类似于 Python 语法的代码,然后向模板传递数据来呈现出最终的文档。
模板可以被继承或者被包含。
可以在模板中定义和导入宏(Macro,批量处理。根据一系列预定义的规则替换一定的文本模式)。
{% macro input(name, type='text', value='') -%}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
{% endmacro %}
macro
,结束时要用endmacro
。宏名称为input
,有三个参数type
、name
、value
。
<p>用户名:{{ input('username') }}p>
<p>密码:{{ input('password', type='password') }}p>
HTML 模板可以使用自动转义来防止 XSS 来自不信任的用户输入。
沙箱可以安全地呈现不受信任的模板。
AsyncIO(异步IO) 支持生成模板和调用异步函数。
I18N 支持 Babel。
模板即时编译为优化的 Python 代码并缓存,或者可以提前编译。
异常指向模板中的正确行以使调试更容易。
可扩展的过滤器、测试、函数、甚至语法。
如果可能的话,应用程序的逻辑属于 Python,但它不应该因为过多地限制功能而使得模板设计者的工作变得困难。
模板文件 model.html
doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body style="background-color: antiquewhite">
<h1>你好世界!h1>
body>
html>
普通文件 index.html
{% extends 'model.html' %}
Python代码
@app.route('/index')
def index():
return render_template('index.html')
页面展示:
Python代码
@app.route('/index')
def index():
users = [
{'name': '孙悟空'},
{'name': '赵云'},
{'name': '林黛玉'},
{'name': '武松'}
]
return render_template('index.html', users=users)
model.html
<body style="background-color: antiquewhite">
{% block content %}{% endblock %}
body>
index.html
{% extends 'model.html' %}
{% block content %}
<div>
<ul>
{% for user in users %}
<li>{{ user.name }}li>
{% endfor %}
ul>
div>
{% endblock %}
页面展示:
Python代码
@app.route('/index')
def index():
num = 3
return render_template('index.html', num=num)
model.html 同循环。
index.html
{% extends 'model.html' %}
{% block content %}
<div>
<p>
{% if num > 10 %}
Hello World<br>
{% elif num < 10 %}
Hello Python<br>
{% else %}
GoodBye<br>
{% endif %}
p>
div>
{% endblock %}
页面展示
过滤器,可以对变量进行修改。
过滤器通过管道符号 |
与变量分隔开,并且在括号中可以包含可选参数。
一个变量可以链接多个过滤器,下一个过滤器过滤的内容是基于上一个过滤器的输出。
upper 大写字母
所有的英文字母都将会被转化为大写字母。
{{ 'hello'|upper }}
lower 小写字母
所有的英文字母都将会被转化为小写字母。
{{ 'HELLO'|lower }}
reverse 反转
所有字符反向输出。
{{ '你好!Python'|reverse }}
title 首字母大写。
每个独立的单词的首字母将会转化为大写。
{{ 'hello world'|title }}
备注: 如果是 helloworld
那么最终转化是 Helloworld
。
capitalize 首字母大写,其余的小写
将第一个单词的首字母转化为大写,其余部分的字母全部转化为小写。
{{ 'gOOD jOB! bOy'|capitalize }}
其他常用过滤器
获取列表的第一个元素
{{ list|first }}
获取列表的最后一个元素
{{ list|last }}
将列表以从小到大重新排序
{{ list|sort }}
求列表中所有值的总和
{{ list|sum }}
获取列表的长度
{{ list|length }}
Python代码
@app.route('/index')
def index():
list = [1, 3, 5, 2, 4, 6, 8, 7]
return render_template('index.html', list=list)
index.html
<div>
首位元素:{{ list|first }}<br>
末位元素:{{ list|last }}<br>
排序:{{ list|sort }}<br>
求和:{{ list|sum }}<br>
长度:{{ list|length }}<br>
div>
页面展示
其他列表过滤器
定义一个反转列表的过滤器。
使用装饰器添加。
@app.template_filter('listreverse')
def list_reverse(li: list):
li.reverse()
return li
使用app实例添加。
def list_reverse(li: list):
li.reverse()
return li
app.add_template_filter(list_reverse, "listreverse")
展示效果
{{ list|listreverse }}
jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'username'
翻译:预期令牌’,‘,得到’username’。
原因:在引入宏定义的时候,没有添加上 name
参数名。
{% macro input(name, type='text', value='') -%}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
{% endmacro %}
<div>
<p>用户名:{{ input('username') }}p>
<p>密码:{{ input('password', type='password') }}p>
div>
解决方法:加上 name
参数名即解决。
<div>
<p>用户名:{{ input(name='username') }}p>
<p>密码:{{ input(name='password', type='password') }}p>
div>