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模板引擎的使用问题就讲到这里,以后在实际使用过程中,再慢慢总结与领会。

1 0
原创粉丝点击