一:渲染模版

要渲染一个模板,通过render_template方法即可。

@app.route('/about/')
def about():
return render_template('about.html',**{'user':'username'})

渲染模版时有两种传递参数的方式:用 var='value' 传递一个参数;使用字典组织多个参数,并且加两个*号转换成关键字参数传入。

python文件调用模板进行渲染的基本使用方法如下:

from jinja2 import loaders, FileSystemLoader, Environment

指定模板文件搜索的开始位置

TemplateLoader = FileSystemLoader(searchpath="./", encoding='utf-8')
TemplateEnv = Environment(loader=TemplateLoader)

这里的文件位置是以searchpath作为基准的,而不是当前文件夹.

template = TemplateEnv.get_template("./test.html")
html = template.render({"config": config})

需要注意的是:
如果传到模板文件的变量config是一个列表(字典)等容器类型;
当config作为整体被使用时,渲染之后不会进行decode,造成的结果就是中文显示不出来,解决办法是在模板文件中将config中的元素一一取出;

模板文件正确写法

{% for i in config %}
i
{ endfor }

有问题的写法

{{config}}  //直接渲染列表整体将造成里面的中文无法正常显示

二:模板概要

Jinja模板是简单的一个纯文本文件,一般用html页面来书写。
复制代码

  1. <html lang="en">

  2. <head>

  3. <title>My Webpage</title>

  4. </head>

  5. <body>

  6. <ul id="navigation">

  7. {% for item in navigation %}

  8. <li><a href="{{ item.href }}">{{ item.caption }}</a></li>

  9. {% endfor %}

  10. </ul>

  11. {{ a_variable }}

  12. {{ user.name }}

  13. {{ user['name'] }}

  14. {# a comment #}

  15. </body>
    18.</html>

转自作者:IT蔷薇
链接:http://www.jianshu.com/p/31a75d3d9270

复制代码

模版讲解:

{{ ... }}:装载一个变量,模板渲染的时候,会使用传进来的同名参数这个变量代表的值替换掉。{% ... %}:装载一个控制语句。{# ... #}:装载一个注释,模板渲染的时候会忽视这中间的值。

三:变量

1)在模板中添加变量,可以使用(set)语句。

{% set name='xx' %}

之后就可以在页面文件中使用name这个变量了。在解释性语言中,变量的类型时运行时确定的,因此,这里的变量可以赋任何类型的值。

上面的语句创建的是全局变量,从定义之后的文件部分中都可以访问 。

2)局部变量

可以使用with语句来创建一个内部的作用域,将set语句放在其中,这样创建的变量只在with代码块中才有效。

{% with foo = 42 %}
{{ foo }}
{% endwith %}

这样,foo变量就只能在with标签间可以使用。

四:控制语句

控制语句都是放在{% ... %}中,并且有一个语句{% endxxx %}来进行结束。

1:if语句
复制代码

{% if kenny.sick %}
Kenny is sick.
{% elif kenny.dead %}
You killed Kenny! You bastard!!!
{% else %}
Kenny looks okay --- so far
{% endif %}

转自:IT蔷薇
链接:http://www.jianshu.com/p/31a75d3d9270

复制代码

2:for循环

1)普通用法

<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>

2)遍历字典

{% for key, value in my_dict.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}

3)在循环中加入else
复制代码

<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no users found</em></li>
{% endfor %}
</ul>

复制代码

4)Jinja2中for循环内置常量
loop.index  当前迭代的索引(从1开始)
loop.index0     当前迭代的索引(从0开始)
loop.first  是否是第一次迭代,返回True\/False
loop.last   是否是最后一次迭代,返回True\/False
loop.length     序列的长度

注意:不可以使用continue和break表达式来控制循环的执行。

五:运算符

+号运算符:可以完成数字相加,字符串相加,列表相加。但是并不推荐使用+运算符来操作字符串,字符串相加应该使用~运算符。-号运算符:只能针对两个数字相减。/号运算符:对两个数进行相除。%号运算符:取余运算。*号运算符:乘号运算符,并且可以对字符进行相乘。**号运算符:次幂运算符,比如2**3=8。in操作符:跟python中的in一样使用,比如{{1 in [1,2,3]}}返回true。~号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}将返回HelloWorld。

六:Jiaja2模版最重要的部分——宏
宏相当于一个搭建好的页面一部分,可以被引入,可以往宏传递参数。可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量,在使用宏时传递参数,从而将宏渲染成为页面的一部分。
比如:定义一个input标签宏

{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{
value|e }}">
{% endmacro %}

在其它地方使用这个宏快速创建出符合要求的input标签:

<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>

1)页面文件中导入宏——import

在开发中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。

import语句的用法跟python中的import类似,可以直接import...as...,也可以from...import...或者from...import...as...。
复制代码

{% import 'forms.html' as forms %}  //导入宏文件
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>  //使用宏
<dt>Password</dt>
<dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>

复制代码

导入模板并不会把当前上下文中的变量添加到被导入的模板中,我们可以在导入的时候使用with context 把上下文传进去:

{% from '_helpers.html' import my_macro with context %}

2)宏文件中引用其它宏——include

include语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置。

{% include 'header.html' %}
Body
{% include 'footer.html' %}

七:模版文件的继承

模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出来,放在父模板中,并且父模板通过定义block给子模板开一个口,子模板根据需要,再实现这个block进行具体内容定义。

比如:父模版base.html如下:
复制代码

<!DOCTYPE html>
<html lang="en">
<head>
{% block head %} //开放一个地方,以待具体赋值
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2008 by <a href="http://domain.invalid/">you</a>;.
{% endblock %}
</div>
</body>
</html>

转自:IT蔷薇
链接:http://www.jianshu.com/p/31a75d3d9270

复制代码

然后定义子模版,对父模板中的block部分进行覆盖书写:
复制代码

{% extends "base.html" %}//1:继承父模板
{% block title %}Index{% endblock %}//2:书写title block
{% block head %}//3:书写head block
{{ super() }}//调用父模板中的内容,如果不调用,则此处会被子模板中书写的内容覆盖掉
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}//4:书写content block
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}

转自:IT蔷薇
链接:http://www.jianshu.com/p/31a75d3d9270

复制代码

另外:模板文件中对block内容的调用,可以使用 self.blockName 的方式。

<title>{% block title %}{% endblock %}</title>
<h1>{{ self.title() }}</h1>//调用title block的内容

注意:在子模板中,所有的标签和代码都要添加到从父模板中继承的block中。否则,这些文本和标签将不会被渲染。(因为子模板相当于把内容嵌入到父模板到block中,而没有写到block中的内容当然不会被嵌入,也就不会被渲染。)

八:过滤器

过滤器是通过(|)符号进行使用的,例如:{{ name|length }}:将返回name的长度。

过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。
Jinja2拥有许多过滤器:(转自:http://www.jianshu.com/p/31a75d3d9270)

abs(value):返回一个数值的绝对值。示例:-1|absdefault(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。示例:name|default('xiaotuo')——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。示例:content|escape或content|e。first(value):返回一个序列的第一个元素。示例:names|firstformat(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标签,如果出现多个空格,将替换成一个空格。trim:截取字符串前面和后面的空白字符。string(value):将变量转换成字符串。wordcount(s):计算一个长字符串中单词的个数。

九:测试器

测试器主要用来判断一个值是否满足某种类型,语法是:if...is...:

{% if variable is escaped%}
value of variable: {{ escaped }}
{% else %}
variable is not escaped
{% endif %}

Jinja2中测试器有:

callable(object):是否可调用。defined(object):是否已经被定义了。escaped(object):是否已经被转义了。upper(object):是否全是大写。lower(object):是否全是小写。string(object):是否是一个字符串。sequence(object):是否是一个序列。number(object):是否是一个数字。odd(object):是否是奇数。even(object):是否是偶数。

十:转义

在模板渲染字符串的时候,字符串有可能包括一些非常危险的字符比如<、>等,这些字符会破坏掉原来HTML标签的结构,更严重的可能会发生XSS跨域脚本攻击,因此如果碰到<、>这些字符的时候,应该转义成HTML能正确表示这些字符的写法。

对于一些不信任的字符串,可以通过{{ content_html|e }}或者是{{ content_html|escape }}的方式进行转义。

如果想关闭自动转义,可以通过{{ content_html|safe }}的方式关闭自动转义。

{%autoescape true/false%}...{%endautoescape%}可以将一段代码块放在中间,来关闭或开启自动转义:

{% autoescape false %}
<p>autoescaping is disabled here
<p>{{ will_not_be_escaped }}
{% endautoescape %}

十一:模版页面中引入静态文件

静态文件主要包括有CSS样式文件、JavaScript脚本文件、图片文件、字体文件等静态资源。

在Jinja中加载静态文件只需要通过url_for全局函数就可以实现:

<link href="{{ url_for('static',filename='about.css') }}">

引入static目录下的about.css文件。

python--jianja2的更多相关文章

  1. python web django base skill

    web框架本质 socket + 业务逻辑 框架实现socket tonado node.js 使用WSGI实现socket django flask 自己实现框架思路 wsgiref socket ...

  2. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  3. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  4. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  5. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  6. 可爱的豆子——使用Beans思想让Python代码更易维护

    title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...

  7. 使用Python保存屏幕截图(不使用PIL)

    起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...

  8. Python编码记录

    字节流和字符串 当使用Python定义一个字符串时,实际会存储一个字节串: "abc"--[97][98][99] python2.x默认会把所有的字符串当做ASCII码来对待,但 ...

  9. Apache执行Python脚本

    由于经常需要到服务器上执行些命令,有些命令懒得敲,就准备写点脚本直接浏览器调用就好了,比如这样: 因为线上有现成的Apache,就直接放它里面了,当然访问安全要设置,我似乎别的随笔里写了安全问题,这里 ...

  10. python开发编译器

    引言 最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便.乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用. ...

随机推荐

  1. svn执行update操作后出现:Error : Previous operation has not finished; run 'cleanup' if it was interrupted.

    svn执行update操作后出现:      Error : Previous operation has not finished; run 'cleanup' if it was interrup ...

  2. 检查文件是否被修改或者被破坏工具 md5

    检查文件和对应的md5值是否一致.

  3. Linux基础命令---lpq查看打印队列

    lpq lpq指令用来显示当前打印队列的状态.如果命令行中没有指定打印机或类,则将显示默认目标上排队的作业. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.ope ...

  4. 解决tomcat重启时报严重: Exception loading sessions from persistent storage的问题

    很多项目在重启时会报:严重: Exception loading sessions from persistent storage的问题.该问题的原因是tomcat的session持久化机制引起的,t ...

  5. 禁止chrome浏览器的缓冲图片以及css等资源文件

    今天做了一个动画的效果,在ff下正常 但是到了谷歌下就不正常了,非常郁闷,看了下是缓存的问题 ,于是度娘了一下发现清理缓存的技巧还是满多的,这里借鉴一下别人的总结,人的大脑有限,下次忘记的时候还可以在 ...

  6. Python sqlalchemy orm 外键关联

    创建外键关联 并通过relationship 互相调用 如图: 实现代码: import sqlalchemy # 调用链接数据库 from sqlalchemy import create_engi ...

  7. 面试神体验之:get和post的区别

    由于本文是用markdown在本地编辑的,粘贴到本地的时候出现了一些页面bug,所以只好贴进代码里面,一些链接失效,望见谅 Get和POST的区别 都9102年了,你们还在问get和post的区别?是 ...

  8. https连接器

    非对称性加密:A生成一份公私钥,将公钥交给需要进行数据传输的B,B发送数据时先用公钥对数据进行加密,然后发送给A,再由A使用私钥进行解密. 但存在漏洞即B如何确认公钥是由A提供的.因此需要一个第三方机 ...

  9. 【BZOJ4031】小Z的房间

    Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...

  10. Github 最简单的认证方式 - Access Token

    Github 本身提供了多种认证方式,所有开发人员可以各取所需. SSH,这是最原始的方式,如果使用git bash只要按照官方文档一步一步配置就好了 小心坑:SSH有可能需要配置代理,否则无法解析服 ...