模板渲染
先创建一个目录,templates,将模板文件放到目录中,默认查找templates目录return render_template("模板文件名字")
指定模板目录
template_folder="模板目录"
app = Flask(__name__, template_folder=r"./demo")
模板传参
return render_template("index.html", username="xxxx")
{{ username }}
context = {
xxx: "xxx"
}
return render_template("index.html", context=context)
{{ context.xxx }}
context = {
xxx: "xxx"
}
return render_template("index.html", **context)
{{ xxx }}
模板过滤器
过滤器是通过管道符号(|)进⾏使⽤的,例如:{{ name|length }},将返回
name的⻓度。过滤器相当于是⼀个函数,把当前的变量传⼊到过滤器中,然后
过滤器根据⾃⼰的功能,再返回相应的值,之后再将结果渲染到⻚⾯中。Jinja2
中内置了许多过滤器,在这⾥可以看到所有的过滤器
- abs(value):返回⼀个数值的绝对值。
- default(value,default_value,boolean=false):如果当前变量没有值,则会
使⽤参数中的值来代替。name|default(‘juran’)——如果name不存在,则会
使⽤juran来替代。boolean=False默认是在只有这个变量为undefined的时
候才会使⽤default中的值,如果想使⽤python的形式判断是否为false,则
可以传递boolean=true。也可以使⽤or来替换。
- escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。例
如:content|escape或content|e。
first(value):返回⼀个序列的第⼀个元素。names|first。
format(value,arags,*kwargs):格式化字符串。例如以下代码: {{ "%s" - "%s"|format('Hello?',"Foo!") }}将输出:Helloo? - Foo!
- last(value):返回⼀个序列的最后⼀个元素。示例:names|last。
- length(value):返回⼀个序列或者字典的⻓度。示例:names|length。
- join(value,d=u’’):将⼀个序列⽤d这个参数的值拼接成字符串。
safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示
例:content_html|safe。
int(value):将值转换为int类型。
- float(value):将值转换为float类型。
- lower(value):将字符串转换为⼩写。
- upper(value):将字符串转换为⼩写。
- replace(value,old,new): 替换将old替换为new的字符串。
- truncate(value,length=255,killwords=False):截取length⻓度的字符串。
- striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将
替换成⼀个空格。
所有的控制语句都是放在{% … %}中,并且有⼀个语句{% endxxx %}来进行结束,Jinja中常用的控制语句有if/for..in..
if:if语句和python中的类似,可以使用>,<,<=,>=,==,!=来进⾏判断,也可以通过and,or,not,()来进行逻辑合并操作
{% if kenny.sick %}
Kenny is sick.
{% elif kenny.dead %}
You killed Kenny! You bastard!!!
{% else %}
Kenny looks okay --- so far
{% endif %}
for…in…:for循环可以遍历任何⼀个序列包括列表、字典、元组。并且可以进
⾏反向遍历
普通的遍历
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
遍历字典
<dl>
{% for key, value in my_dict.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
如果序列中没有值的时候,进入else
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no users found</em></li>
{% endfor %}
</ul>
并且Jinja中的for循环还包含以下变量,可以⽤来获取当前的遍历状态
另外,不可以使⽤continue和break表达式来控制循环的执行。
宏和import
宏
模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以
将⼀些经常用到的代码片段放到宏中,然后把⼀些不固定的值抽取出来当成⼀
个变量
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
以上例⼦可以抽取出了⼀个input标签,指定了⼀些默认参数。那么我们以后创建input标签的时候,可以
通过他快速的创建:
1 <p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>
import语句
在真实的开发中,会将⼀些常⽤的宏单独放在⼀个⽂件中,在需要使⽤的时
候,再从这个⽂件中进⾏导⼊。import语句的⽤法跟python中的import类似,
可以直接import…as…,也可以from…import…或者from…import…as…,假
设现在有⼀个⽂件,叫做macro.html,⾥⾯有两个宏分别为input和textarea
macro.html:
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{% endmacro %}
{% macro textarea(name, value='', rows=10, cols=40) %}
<textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}</textarea>
{% endmacro %}
导⼊宏的例⼦
1.import…as…形式
{% import 'macro.html' as macro %}
<tr>
<td>⽤户名:</td>
<td>{{ macro.input('username') }}</td>
</tr>
2.from…import…as…/from…import…形式
{% from "macro.html" import input %}
<tr>
<td>密码:</td>
<td>{{ input("password",type="password") }}</td>
</tr>
另外需要注意的是,导⼊模板并不会把当前上下⽂中的变量添加到被导⼊的模
板中,如果你想要导⼊⼀个需要访问当前上下⽂变量的宏,有两种可能的⽅法
- 显式地传⼊请求或请求对象的属性作为宏的参数
- 与上下⽂⼀起(with context)导⼊宏
与上下⽂中⼀起(with context)导⼊的⽅式
{% import 'macro.html' as macro with context %}
include和set
include语句
include
语句可以把⼀个模板引⼊到另外⼀个模板中,类似于把⼀个模板的代
码copy到另外⼀个模板的指定位置
{% include 'header.html' %}
主体内容
{% include 'footer.html' %}
赋值(set)语句
{% set name='xxx' %} #全局
{% with %}
{% set name='xxx' %} # 局部
{% endwith %}
{% with xxx='' %} # 局部
{% endwith %}
有时候我们想在在模板中添加变量,这时候赋值语句(set)就派上⽤场了
{% set name='ecithy' %}
那么以后就可以使⽤ name 来代替 juran 这个值了,同时,也可以给他赋值为
列表和元组:
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
赋值语句创建的变量在其之后都是有效的,如果不想让⼀个变量污染全局环
境,可以使⽤ with
语句来创建⼀个内部的作用域,将 set 语句放在其中,这样
创建的变量只在 with
代码块中才有效
{% with %}
{% set foo = 42 %}
{{ foo }} foo is 42 here 4
{% endwith %}
也可以在 with 的后面直接添加变量,比如以上的写法可以修改成这样:
{% with foo = 42 %}
{{ foo }}
{% endwith %}
这两种方式都是等价的,⼀旦超出 with
代码块,就不能再使⽤ foo 这个变量
了。
模版继承
作用:代码的复用,和类的思想类似(可继承、重写){% extends '父模板.html' %}
继承的注意点
1. {% extends 'base.html' %} 放到block模块上面
2. 子模板不可以多继承
3. 子模板只能重写父模板中的block,自己定义的block不显示,没有在block模块中的标签也不会显示
4. 调用父模板中的block {{ super() }}
5. 父模板中block,是可以嵌套的
Flask中的模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出
来,放在父模板中,并且父模板通过定义 block 给⼦模板开⼀个口,子模板根
据需要,再实现这个 block ,假设现在有⼀个 base.html 这个⽗模板
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="base.css" />
<title>{% block title %}{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
<div id="body">{% block body %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2008 by <a href="http://domain.invalid/">you</a>
{% endblock %}
</div>
</body>
</html>
以上⽗模板中,抽取了所有模板都需要⽤到的元素 html 、 body 等,并且对于
⼀些所有模板都要用到的样式⽂件 style.css 也进行了抽取,同时对于⼀些子
模板需要重写的地方,比如 title 、 head 、 body 都定义成了 block ,然后
子模板可以根据自己的需要,再具体的实现。
{% extends "base.html" %}
{% block title %}⾸⻚{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.detail{
color: red;
}
</style>
{% endblock %}
{% block content %}
<h1>这⾥是⾸⻚</h1>
<p class="detail">
⾸⻚的内容
</p>
{% endblock %}
首先第⼀行就定义了子模板继承的父模板,并且可以看到⼦模板实现了 title
这个 block ,并填充了自己的内容,再看 head 这个 block ,里面调用了
super() 这个函数,这个函数的⽬的是执行父模板中的代码,把父模板中的内
容添加到子模板中,如果没有这⼀句,则父模板中处在 head 这个 block 中的
代码将会被子模板中的代码给覆盖掉。
另外,模板中不能出现重名的 block
,如果⼀个地方需要用到另外⼀个 block
中的内容,可以使用 self.blockname 的方式进行引用
<title>
{% block title %}
这是标题
{% endblock %}
</title>
<h1>{{ self.title() }}</h1>
以上示例中 h1 标签重⽤了 title
这个 block
中的内容,子模板实现了 title
这个 block
,h1 标签也能拥有这个值。另外,在子模板中,所有的文本标签和代码都要添加到从父模板中继承的 block
中。否则,这些文本和标签将不会被渲染
加载静态资源文件
创建static目录,静态资源文件放到这个目录下面
<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
<script src="{{ url_for('static', filename='js/index.js') }}"></script>
<img src="{{ url_for('static', filename='images/demo.jpg') }}" alt="">
还可以自定义资源文件的目录
app = Flask(__name__,static_folder='./static')