Flask学习总结笔记(4)-- Jinja2模板引擎之二
来源:互联网 发布:河北大学网络教育 编辑:程序博客网 时间:2024/05/19 02:28
Jinja2模板引擎官方文档详细介绍了其中的API函数、沙箱、模板设计文档等,这里主要就一些常用的知识点进行总结。
0x01 模板基础
常见的几种模板语句如下:
{%...%} #运行Jinja2的语句;{{…}} #在页面中打印Jinja2运行的结果{#...#} #注释
看下面的例子:
(1)views.py
from flask import render_template@app.route('/index')def index(): return render_template('index1.html', name='kikay', age=20)
(2)templates文件夹下新建模板index1.html:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Test</title></head><body><p>测试</p><p>直接输出姓名:{{name}}</p>{#这是注释:判断是否存在age#}{%if age%}<p>年龄:{{age}}</p>{%else%}<p>不存在年龄</p>{%endif%}</body></html>
输出效果:
如果想输入原始的Jinja2语句,而不是作为特殊字符进行解析,可以包含在{%raw%}…{%%endraw}
中:
views.py
@app.route('/raw')def raw(): return render_template('raw.html',name='kikay')
raw.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Raw</title></head><body><div> <p>姓名:{{name}}</p> {%raw%} <p>转义姓名:{{name}}</p> {%endraw%}</div></body></html>
效果如下:
上面的例子都需要调用render_template('*.html',var_key=***)
来渲染模板。其中的函数render_template是把Jinja2模板引擎集成到程序中。Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。
0x02 控制语句
添加一些控制语句,index2.html如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>{{title}}</title></head><body><div> {%if author%} <h1>Hello,{{author}}</h1> {%else%} <h1>Nobody</h1> {%endif%}</div></body></html>
views.py:
@app.route('/index2')def index2(): author='kikay' return render_template('index2.html', author=author)
输出:
注释掉author:
@app.route('/index2')def index2(): author='kikay' return render_template('index2.html') #author=author)
效果如下:
当参数不存在时,Jinja2模板在渲染时直接忽略掉。更复杂一些,现在还要输出作者好友的列表。
index3.html:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Firends</title></head><body><div> <h1>作者:{{author.name}}</h1> <table> <thread> <th>姓名</th> <th>年龄</th> </thread> {%for f in author.friends%} <tr> <td>{{f.name}}</td> <td>{{f.age}}</td> </tr> {%endfor%} </table></div></body></html>
views.py:
@app.route('/index3')def index3(): author={ 'name':'kikay', 'age':20, 'friends':[ {'name':'Andy','age':60}, {'name':'Tom','age':29}, {'name':u'小花','age':18} ] } return render_template('index3.html', author=author)
效果如下:
这里需要指出的是,输出带有中文时,注意编码的问题。类似于Python中函数的定义,Jinja2模板引擎中的macro关键字可以看成是一个函数的定义:
{%macro showinfo(info)%}这是{{info}}!!!<br />{%endmacro%}{%for info in infos%}{{showinfo(info)}}{%endfor%}
0x03 模板继承
随着应用的拓展,我们可能在多个页面中使用了相同的HTML代码,并且需要每一个页面都同步,和其他模板引擎一样,Jinja2也支持模板继承。我们在templates下新建一个layout_base.html文件,内容如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> {%if title%} <title>{{title}}</title> {%else%} <title>No title</title> {%endif%} <!--一引入js文件--> {%block script%} <script src="test.js"></script> {%endblock%}</head><body><div> {%block t1%}{%endblock%} <p>----------模板分隔符------------</p> {%block t2%}{%endblock%}</div></body></html>
里面有3个block标签,这是为继承该模板的html模板替换使用的。新建index4.html继承layout_base.html:
{%extends 'layout_base.html'%}{%block script%}{{super()}}<script src="test2.js"></script>{%endblock%}{%block t1%}{%if author%}<h1>Hello,{{author.name}}</h1>{%else%}<h1>Nobody</h1>{%endif%}{%endblock%}{%block t2%}<table> <thread> <th>姓名</th> <th>年龄</th> </thread> {%for f in author.friends%} <tr> <td>{{f.name}}</td> <td>{{f.age}}</td> </tr> {%endfor%}</table>{%endblock%}
效果如下:
extends指明该模板是从哪个模板继承而来的。上面例子中的{{super()}},因为模板中其中包含的内容不是空的,所以需要用{{super()}}来获取原来的内容。如果一个html中包含1个以上的extends标签就会报错,即最多继承于1个模板。
0x04 模板设计
Flask集成了Bootstrap包,可以使用Flask-Bootstrap来渲染模板,首先需要安装(利用pip):
pip install flask-bootstrap
具体过程参见以前的博客(Flask学习总结笔记(1)– 环境配置)。
在__init__.py
中初始化Flask-Bootstrap:
from flask.ext.bootstrap import Bootstrap
修改后的完整__init__.py
如下:
#!flask/bin/env python#coding:utf-8__author__ = 'kikay'from flask import Flaskfrom flask.ext.bootstrap import Bootstrap#定义app对象app=Flask(__name__)#定义Bootstrap对象bootstrap=Bootstrap(app)from app import views
完成Flask-Bootstrap初始化后,就可以在程序中使用一个包含全部Bootstrap文件的基模板。这个模板利用Jinja2的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中就有用来引入 Bootstrap 的元素。(官方教程),关于Bootstrap的内容可以参看我的博客(Bootstrap学习总结笔记)。
下面是实现一个导航样式的例子:
bootstrap.html
<!--引入Flask-Bootstrap中的基模板-->{%extends 'bootstrap/base.html'%}<!--添加html属性-->{%block html_attribs%}lang="zh-cn"{%endblock%}<!--添加metas标签-->{%block metas%} {{super()}} <meta charset="UTF-8">{%endblock%}<!--添加网页的样式-->{%block styles%} {{super()}} <link rel="stylesheet" href="{{url_for('.static',filename='css/block.css')}}">{%endblock%}{%block scripts%} {{super()}} <script src="{{url_for('.static',filename='js/block.js')}}"></script>{%endblock%}<!--网页标题-->{%block title%}Flask-Bootstrap{%endblock%}<!--网页导航-->{%block navbar%}<div class="container"> <nav class="navbar navbar-inverse"> <div class="navbar-header"> <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target="#navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="#" class="navbar-brand">网站标题</a> </div> <div class="collapse navbar-collapse" id="navbar"> <ul class="nav navbar-nav"> <li class="active"><a href="#">首 页</a></li> <li><a href="#">新闻</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> 下拉菜单 <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="#">菜单1</a></li> <li><a href="#">菜单2</a></li> <li><a href="#">菜单3</a></li> </ul> </li> </ul> <form class="nav navbar-form navbar-right"> <div class="form-group"> <input type="text" class="form-control" placeholder="用户名"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="密码"> </div> <div class="form-group"> <button type="submit" class="btn btn-primary form-control">提 交</button> </div> </form> </div> </nav></div>{%endblock%}<!--网页正文-->{%block content%}<div class="container"> <div class="page-header"> {%if author%} <h1>Hello,{{author.name}}</h1> {%else%} <h1>Nobody</h1> {%endif%} </div> <div class="col-center-block"> <!--展示朋友列表--> {%if author.friends%} <table class="table table-bordered table-striped table-hover table-condensed"> <thead class="alert-danger"> <th>姓名</th> <th>年龄</th> </thead> {%for f in author.friends%} <tr class="alert-success"> <td>{{f.name}}</td> <td>{{f.age}}</td> </tr> {%endfor%} </table> {%endif%} </div></div><script></script>{%endblock%}
views.py:
@app.route('/bootstrap')def bootstrap(): author={ 'name':'kikay', 'age':20, 'friends':[ {'name':'Andy','age':60}, {'name':'Tom','age':29}, {'name':u'小花','age':18} ] } return render_template('bootstrap.html', author=author, title='Bootstrap')
效果如下:
看下源代码,可以更好理解这种渲染的效果。
<!--引入Flask-Bootstrap中的基模板--><!DOCTYPE html><htmllang="zh-cn"> <head> <title>Flask-Bootstrap</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta charset="UTF-8"> <!-- Bootstrap --> <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/static/css/block.css"> </head> <body><div class="container"> <nav class="navbar navbar-inverse"> <div class="navbar-header"> <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target="#navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="#" class="navbar-brand">网站标题</a> </div> <div class="collapse navbar-collapse" id="navbar"> <ul class="nav navbar-nav"> <li class="active"><a href="#">首 页</a></li> <li><a href="#">新闻</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> 下拉菜单 <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="#">菜单1</a></li> <li><a href="#">菜单2</a></li> <li><a href="#">菜单3</a></li> </ul> </li> </ul> <form class="nav navbar-form navbar-right"> <div class="form-group"> <input type="text" class="form-control" placeholder="用户名"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="密码"> </div> <div class="form-group"> <button type="submit" class="btn btn-primary form-control">提 交</button> </div> </form> </div> </nav></div><div class="container"> <div class="page-header"> <h1>Hello,kikay</h1> </div> <div class="col-center-block"> <!--展示朋友列表--> <table class="table table-bordered table-striped table-hover table-condensed"> <thead class="alert-danger"> <th>姓名</th> <th>年龄</th> </thead> <tr class="alert-success"> <td>Andy</td> <td>60</td> </tr> <tr class="alert-success"> <td>Tom</td> <td>29</td> </tr> <tr class="alert-success"> <td>小花</td> <td>18</td> </tr> </table> </div></div><script></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="/static/js/block.js"></script> </body></html>
在Flask-Bootstrap中,支持的block样式如下表:
这里不再一一介绍,在实际应用中可以自己体会。另外上面用到了url_for函数做路由的映射,具体使用可以参见我前面的博客(Flask学习总结笔记(2)– Hello world程序)中关于构造Url的内容。这里引入了js和css文件,对应的文件结构如下:
关于Flask-Jinja2模板引擎的使用问题就讲到这里,以后在实际使用过程中,再慢慢总结与领会。
- Flask学习总结笔记(4)-- Jinja2模板引擎之二
- Flask学习总结笔记(3)-- Jinja2模板引擎之一
- Flask-Jinja2模板学习总结
- Flask笔记(2)--flask的jinja2模板引擎
- Flask入门(二)Jinja2 模板
- Flask模板引擎——Jinja2
- Python学习:Flask框架和jinja2模板
- 《Flask Web开发》学习笔记之bug--(5)【jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'endlock'】
- 《Flask Web开发》学习笔记之bug--(9)【jinja2.exceptions.TemplateSyntaxError: unexpected '%'】
- Flask(Jinja2) 服务端模板注入漏洞
- Flask Jinja2模板
- Python Flask Web 第四课 —— 模板引擎Jinja2
- Flask——Jinja2 学习笔记
- python中模板引擎Jinja2学习
- Flask零基础到项目实战(三)Jinja2模板系统 (二)
- flask-cache 缓存Jinja2模板之源码解读
- Flask web 开发 Jinja2 模板
- Flask中的Jinja2模板使用
- Handler基本使用(二)new Message 、 Handler.obtainMessage和Message.obtain
- 选择排序
- composer安装指定版本的laravel
- JavaScript易错知识点整理
- 关于excel导出功能的一个很奇怪的bug
- Flask学习总结笔记(4)-- Jinja2模板引擎之二
- TCP的三次握手(建立连接)和四次挥手(关闭连接)
- JDK1.7的安装步骤(图解)
- 编译MeshLab(2)—VS中引用Lib文件
- 欢迎使用CSDN-markdown编辑器
- 什么是好的API设计?
- CodeForces 611B - New Year and Old Property(搜索)
- Shell编程中函数部分的相关讲解
- 设计器弹出窗口信息无法显示