模板引擎
概念: 模板引擎就是一个按照一定的语法格式, 使用视图的参数进行替换的一个过程
jinjia2模板引擎
是由flask开发组人员开发的,
一. jinjia2的使用
(1) 准备templates目录
目录结构为:
project
manage.py
templates/
app/
index.html
(2) 准备模板文件
在templates下新建一个index.html
<h2>{{hello}}</h2>
模板中使用变量:
- 视图传递给模板的数据
- 遵循标识符的命名规则
- 语法是
{{关键字参数的名称}}
- 如果当前变量不存在, 则插入的是空字符串(不报错)
(3) 视图函数
@app.route('/')
def index():
return render_template('index.html', hello='hello')
(4) 视图 返回模板
-
render_template('文件名.html', 关键字参数=值..)
def test(): g.name = "张三" # 使用变量g传递参数 g.age = 18 render_template('index.html', hello='hello') # 使用关键字传递参数 # 如果模板文件存在文件夹嵌套 return render_template('app/hello.html')
-
render_template_string()
render_template_string('<h1 style="color:red;">{{name}}</h1>', name='李四') # 简短模板返回
二. 模板中常用的函数
函数名 | 函数说明 |
---|---|
upper | 全部大写 |
lower | 全部小写 |
title | 每个单词的首字母大写 |
capitalize | 首字母大写 |
trim | 去掉两侧空白 |
striptags | 去掉HTML标签 |
safe | 原样显示HTML标签, 不转义 |
格式: {{g.name|upper}}
{{g.name|first}}
三. 标签
格式:
{% if 条件%}
..
{% elif %}
..
{% else %}
..
{% endif %}
常用运算符:
==,>=,<=,!=,>,<,and,or,in,not in
注意:
在django里运算符两侧需要存在空格, 在flask里不需要, 推荐两侧添加空格
实例:
{% if var2 == 'abcd' %} # 都采用这中方式
<h2>相等</h2>
{% endif %}
(2) 循环
格式为:
{% for i in 变量名 %}
..
{% else %} # 变量不存在时,走else
..
{% endfor %}s
实例:
{% for i in range(10) %}
<li>{{ i }}</li>
{% endfor %}
四. 注释
格式:
{# 单行和多行的注释 #}
五. 文件包含
格式:
{% include '文件名.html'%}
用法:
一般会将一个网站的公共部分的页面导入进来, 减少代码的冗余和后期代码的维护
实例:
{% include 'nav.html' %}
{% include 'app/hello.html' %}
六. 宏的使用
概述: 采用类似于Python的函数的形式, 进行定义和调用, 通常把特定功能的显示定义成一个宏, 哪里使用, 就在哪里调用, 避免代码冗余
宏的定义:
{% macro 宏的名字(形参名='形参默认值') %}
内容
{% endmacro %}
宏的调用:
{{ 宏的名字(实参) }}
实例:
{% macro show_name(name='李四') %} # 形参且有默认值
{% macro show_name(name) %} # 没有默认值, 实参可传可不传
<h2>{{ name }}</h2>
{% endmacro %}
# 调用
{{ show_name('张三') }}
{{ show_name() }} # ok 如果有形参(不含形参默认值时),不传参不会保错
{{ show_name('张三', '李四') }} # error 传递多个参数会报错
{{ show_name(var) }} # ok 接收视图传递的数据
宏的导入:
from 'nav.html' import show_name
实例:
{#{% from 'forms.html' import input %}#}
{% from 'forms.html' import input,textarea %} # 导入多个宏
{% from 'forms.html' import input as input_field %} # 导入同时起别名
<form action="">
<dl>
<dt>用户名</dt>
{# <dd>{{ input('username') }}</dd>#}
<dd>{{ input_filed('username') }}</dd>
<dt>密码</dt>
<dd>{{ input('userpass','password') }}</dd>
<dt>确认密码</dt>
<dd>{{ input(name='repass',type='password') }}</dd>
<dt>个人信息</dt>
<dd>{{ textarea('userinfo') }}</dd>
</dl>
</form>
{% import 'forms.html' as forms %} # 导入同时起别名
<form action="">
<dl>
<dt>用户名</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>密码</dt>
<dd>{{ forms.input('userpass','password') }}</dd>
<dt>确认密码</dt>
<dd>{{ forms.input(name='repass',type='password') }}</dd>
<dt>个人信息</dt>
<dd>{{ forms.textarea('userinfo') }}</dd>
</dl>
</form>
注意:
只能在宏的定义的下方去调用
七. 模板的继承
flask通过模板的继承将许多重复的元素抽取出来, 放在base(parents)模板中, 通过block给子模板提供替换的位置
定义base.html基础模板
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="UTF-8">
<title>{% block title %}title{% endblock %}</title>
{% block css %}
<link rel="stylesheet" href="xxx.css">
{% endblock %}
{% block script %}
{% endblock %}
{% endblock %}
</head>
<body>
{% block nav %}
{% include 'nav.html' %}
{% endblock %}
<div class="content">
{% block content %}
<h2>我是base页面的content默认内容</h2>
{% endblock %}
</div>
{% block footer %}
{% include 'footer.html' %}
{% endblock %}
</body>
</html>
子模板index.html
{% extends 'base.html' %}
{% block title %}
我是首页
{% endblock %}
{% block css %}
{{ super() }} # 调用父html样式
<style type="text/css">
li{ width: 200px; height: 100px; color: red; }
</style>
{% endblock %}
{% block content %}
<ul>
<li>内容1</li>
<li>内容2</li>
<li>内容3</li>
</ul>
{% endblock %}
模板的继承
{%extends '文件名.html'%}
注意:
- 调用block内的原来的内容 使用
{{ super() }}
八. flask-bootstrap
(1) 安装
pip install flask-bootstrap
(2) 使用
from flask_bootstrap import Bootstrap # 导入
bootstarp = Bootstrap(app) # 实例化对象
(3) 创建base页面
{% extends 'bootstrap/base.html' %}
{% block content %}
首页
{% endblock %}
(4) bootstrap/base.html常用的block说明
block标签 | 说明 |
---|---|
doc | 整个HTML文档 |
HTML | HTML的整个标签 |
head | 替换head标签 |
title | title标题 |
styles | 引入css |
metas | 一组meta标签 |
body | 整个body体 |
navbar | 导航条 |
content | 主体内容 |
scripts | 导入js |
注意: 如果继承了bootstrap/base.html 替换之后没有任何样式, 查看是否调用了super()
(5) 自定义bootstrap的base页面
base.html页面
{% extends 'bootstrap/base.html' %}
{% block navbar %}
<nav class="navbar navbar-inverse" style="border-radius: 0px;">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"><span class="glyphicon glyphicon-glass" aria-hidden="true"></span></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
<li><a href="#">个人中心</a></li>
<li><a href="#">我的</a></li>
<li><a href="#">你的</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li><a href="#">注册</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
{% endblock %}
{% block content %}
<div class="container">
{% block tcontent %}
{% endblock %}
</div>
{% endblock %}
(6) 自定义错误页面
{% extends 'boot_base.html' %}
{% block title %}
{{ title }}
{% endblock %}
{% block tcontent %}
<div class="alert alert-danger" role="alert">{{ info }}</div>
{% endblock %}
处理错误的视图
@app.errorhandler(404)
def page_not_found(e):
return render_template('error.html',title='404NOTFOUND', info=e)
@app.errorhandler(500)
def page_not_found(e):
return render_template('error.html',title='500ERROR', info=e)
九. url_for()
1. 根据视图函数名, 反向构造路由地址, 参数为get传参
return url_for('index', name='zs',age=18)
2. 构造完整的url地址
return url_for('index', name='zs',age=18, _external=True) # _external=True构造完整的url地址
3. 在模板中使用url_for()
<p><a href="{{ url_for('index') }}">回到首页</a></p>
十. 视图传递多个参数
(1) 使用全局变量g
def index():
g.name='zs'
g.age= 18
return render_template('boot_index.html')
在模板中使用:
{{g.name}}
{{g.age}}
(2) 使用**locals()
def index():
a = 1
b = 2
return render_template('boot_index.html', **locals())
(3) 将字典变成关键字参数
def index():
return render_template('boot_index.html', **{'a':1, 'b':2})
(4) 元素传参
def index():
return render_template('boot_index.html', a=1, b=2)
十一. 加载静态资源
(1) 目录结构
project/
templates/
static/
link.css
1.jpg
manage.py
(2) 在模板中加载静态资源
<img src="{{ url_for('static', filename='1.jpg' ) }}" alt="">
(3) 如果文件外层有目录嵌套, 则在filename前添加路径
<img src="{{ url_for('static', filename='img/1.jpg' ) }}" alt="">
(4) 修改默认静态资源文件夹的名称
app = Flask(__name__, static_folder='static', template_folder='templates') # 修改静态文件夹名和模板名
网友评论