什么是Jinja2
Jinja2是Python下一个被广泛应用的模版引擎,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能。其中最显著的一个是增加了沙箱执行功能和可选的自动转义功能,这对大多应用的安全性来说是非常重要的。
基于unicode并能在python2.4之后的版本运行,包括python3。
如何使用Jinja2
要想使用Jinja2模板,需要从flask导入render_template函数,然后在路由函数中调用render_template函数,该函数第一个参数就是模板名字。模板默认保存在目录。
最简单的模板文件就是普通的HTML文件,但静态文件没什么意义,需要在访问路由时传入响应的参数,并在模板中以一定的样式显示在浏览器中,因此,需要用到render_template函数的关键字参数。假设有一个模板文件hello.html,代码如下:
<h1> hello,{{name}}.</h1>
这个用{{......}}括起来的部分就是模板表达式。在使用render_template函数调用模板文件hello.html时,需要通过关键字参数指定name值。
render_template('hello.html',name='star')
返回给客户端时,{{name}}会被替换成star.
网页输出代码
<h1> hello,star.</h1>
jinja2常用语法
1. 变量显示语法: {{ 变量名 }}
2. for循环:
{% for i in li%}
{% endfor %}
3. if语句
{% if user == 'westos'%}
{% elif user == 'hello' %}
{% else %}
{% endif%}
数据显示
# templates目录里面建立mubna.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<p>变量:{{ name }}</p>
<p>列表:{{ li }}</p>
<p>列表元素:
{% for item in li %}
<br/>{{ item }}
{% endfor %}</p>
<p>字典:{{ d }}</p>
<p>字典元素:
{{ d.a }}
{{ d['b'] }}</p>
<p>对象:{{ u }}</p>
<table>
<tr>
<td>用户</td>
<td>密码</td>
</tr>
<tr>
<td>{{ u.name }}</td>
<td>{{ u.passwd }}</td>
</tr>
</table>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
class User(object):
def __init__(self, name, passwd):
self.name = name
self.passwd = passwd
def __str__(self):
return "<User: %s>" %(self.name)
@app.route('/')
def index1():
name = "sheen is cute !!"
li = [1, 2, 4, 5]
d = dict(a=1, b=2)
u = User("westos", "passwd")
return render_template('muban.html',
name = name,
li = li,
d = d,
u = u
)
app.run()
模板中的过滤器
服务端给客户端返回的数据可能来自于多种数据源。这些数据格式可能并不能满足客户端需求,就需要对数据进行再加工。
过滤器需要放在模板表达式变量的后面,与变量之间用'|'分割,{{ vlaue|upper}}将value英文字母都转换为大写形式。
编写一个时间过滤器,将时间戳转换为特定格式的字符串时间
from flask import Flask, render_template
import time
app = Flask(__name__)
def time_format(value,format="%Y-%m-%d %H:%M:%S"):
# 时间戳----> 元组
t_time = time.localtime(value)
# 元组 ----> 指定字符串
return time.strftime(format,t_time)
# 第一个参数是过滤器函数,第二个参数是过滤器名称
app.add_template_filter(time_format,'time_format')
@app.route('/chtime/')
def chtime():
return render_template('chtime.html',timestamp = time.time())
app.run()
# templates/目录下的chtime.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
时间戳
{{ timestamp }}
<br/>
格式化后的时间
{{ timestamp | time_format }}
</body>
</html>
宏操作
在编写python程序时,会有很多地方调用同样或类似的代码。这种情况,可以把重复使用的代码放到函数或类中,只需要访问函数或类的实例就可以实现代码复用。Jinja2 模板中使用宏来防止代码冗余。
Jinja2 模板中的宏需要放到{%......%},使用修饰,支持参数,并且使用{% endmacro %}结束
如果宏要被多个模板文件共享,就需要将宏单独放到一个模板文件中,然后使用{% import ….%}指令导入该模板
调用宏,实现登陆页面的模板继承
## templates/目录下的macro.html
{% macro input(type, name, text ) %}
<div class="form-group">
<label>{{ text }}</label>
<input name={{ name }} type={{ type }} class="form-control">
</div>
{% endmacro %}
# # templates/目录下的login.html
{% extends "base.html" %}
{% block title %}
登陆
{% endblock %}
{% block content %}
<div class="container container-small">
<h1>登录
<small>没有账号?<a href="signup.html">注册</a></small>
</h1>
{# /*将表单信息提交给/login路由对应的函数进行处理, 并且提交信息的方式为post方法, 为了密码的安全性*/#}
<form action="/login/" method="post">
<!--<div class="form-group">-->
<!--<label>用户名/手机/邮箱</label>-->
<!--<input name="user" type="text" class="form-control">-->
<!--</div>-->
{% import 'macro.html' as macro %}
{#调用宏模板#}
{{macro.input('text', 'user', "用户名/手机/邮箱" )}}
{{macro.input('password','passwd', "密码" )}}
<!--<div class="form-group">-->
<!--<label>密码</label>-->
<!--<input name="passwd" type="password" class="form-control">-->
<!--</div>-->
<div class="form-group">
<button class="btn btn-primary btn-block" type="submit">登录</button>
</div>
<div class="form-group">
<a href="#">忘记密码?</a>
</div>
<!--获取服务器传递给后台的变量message, jinja2模板引擎里面的语法-->
{% if message %}
<p style="color: red">{{ message }}</p>
{% endif %}
</form>
</div>
{% endblock %}
#主程序
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/login/')
def login():
return render_template('login.html')
app.run()
模板继承
Jinja2模板还有另一种代码复用技术,就是模板继承。当一个模板被另外的模板继承时,可以通过{{ super() }} 访问父模板的资源。在一个模板中继承另一个模板,需要extends 指令。如 child.txt 模板文件从 parent.txt 继承的代码
{% extends ‘parents.txt’ %}
child.txt 从parent.txt模板继承后,会自动使用parent.txt 中的所有代码,但要放在
{% block xxxx%} .... {% endblock %}
中的代码需要child.txt中使用{{super() }}引用。其中,xxxx是块(block)的名字
模板继承语法:
1. 如何继承某个模板?
{% extends "模板名称" %}
2. 如何挖坑和填坑?
挖坑:
{% block 名称 %}
默认值
{% endblock %}
填坑:
{% block 名称 %}
{% endblock %}
3. 如何调用/继承被替代的模板?
挖坑:
{% block 名称 %}
默认值
{% endblock %}
填坑:
{% block 名称 %}
#如何继承挖坑时的默认值?
{{ super() }}
# 后面写新加的方法.
........
{% endblock %}
#templates目录下建立parent.html模板文件
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="UTF-8">
<title>{% block title %}hello{% endblock %}</title>
{% endblock %}
</head>
<body>
I LOVE PYTHON! <br/>
{% block body %}
Cute,{{ text }}
{% endblock %}
</body>
</html>
#templates目录下建立child.html模板文件
{% extends 'parent.html' %}
{% block title %}
{#继承挖坑时的默认值:{{ super() }}#}
{{ super() }}-{{ text }}
{% endblock %}
{% block body %}
<h1>{{ super() }},Beauty!</h1>
{% endblock %}
# 主程序
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('child.html',text = 'sheen')
if __name__ == '__main__':
app.run()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。