jinja模板语法与dajngo模板语法相似,不过它更倾向于pthon的语法,没有特殊说明,则和django模板使用方法一只
一 for 循环
使用如{% for x in xx %} ... {{% else %}}...{% endfor %}语句来进行循环控制:
- range
{% for i in range(5, 1, -1) %} {{ i }} {% endfor %}
- loop.index 从1开始
{% for i in range(5, 1, -1) %} {{ loop.index }}{{ i }} {% endfor %}
- loop.index0 从0开始
- loop.first 判断是否是第一次迭代
- loop.last 判断是否是最后一次迭代
- loop.length 序列长度
- 遍历字典 语法和
python
一样,可以使用items()
、keys()
、values()
、iteritems()
、iterkeys()
、itervalues()
{% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}
二 过滤器
过滤器“|”:形如“{{ var | xxx }}”使用过滤器将变量“var”处理后再渲染展示出来,管道符号“|”前面为变量,后面是一个过滤器(过滤器就相当于一个函数),最外层可以是{{ ... }}或者{% ... %}。常用的过滤器有:
- abs:返回变量的绝对值。
- default(value, boolean=False):给变量设置默认值,当变量不存在时,则使用设置的默认值“value”;如果设置了boolean为True,且变量存在时,当它的Python计算结果为False时,也会使用设置的默认值,比如变量的值为None,[],''等。
- or:or不是过滤器,但是效果相当于default过滤器,当有多个变量时,按照Python中or的逻辑,当有一个变量存在且Python计算结果为True时,取其值,不存在(也算作False)或者Python计算机结果为False时,则继续检查下一个变量。例如:{{ var | default('什么也没有', boolean=True) }}的效果与{{ var or '什么也没有' }}的效果是一样的。
- length:给出前面变量的“长度”,比如字典、列表等的元素个数。
- escape:将值为字符串的变量中的<、>等HTML中的特殊符号转义成普通字符串。如果没有转义,字符串中含有HTML标签等特殊符号的话,浏览器会将它解释为HTML的内容,就不再是原先的字符串了。由于jinja2是开启了自动转义的,所以变量的字符串是什么,HTML渲染展示的就是什么,这时候就用不着escape过滤器。可以使用{% autoescape off %}{% endautoescape %}来关闭处于其中的HTML内容的自动转义,这时候想要其中的某个字符串进行转义的话,就可以使用这个过滤器了。
- safe:关闭变量字符串的自动转义。safe是针对变量的,而{% autoescape on/off %}{% endautoescape %}是打开/关闭处于其中的HTML内容的自动转义。
- first:返回序列的第一个元素。
- last:返回序列的最后一个元素。
- format:格式化字符串,与Python中的%用法类似(只能是%,不能是{}占位符),例如:{{ "这是%s27"|format("Python") }},渲染结果为“这是Python27”。
- join(d=u''):返回使用d的值来将序列中的元素连接在一起的字符串,类似Python中的join方法。
- int:将值转换为int类型。
- float:将值转换为float类型。
- lower:将字符串转换为小写。
- upper:将字符串转换为大写。
- replace(old, new):将字符串中子串old替换为新的子串new。
- string:将变量转换为字符串。
- truncate(length=255):只截取字符串的前length个字符。
- striptags:删除字符串中的所有HTML标签,如果字符串中有多个连续的空格,则替换成一个空格。
- wordcounts:统计一个字符串中的单词个数。
- sort(value,reverse=False,case_sensative=False,attribute=None) 对可迭代的对象进行排序,默认情况下以升序 大小写不敏感的方式排序。
- sum(iterable,attribute=None,start=0) 对可迭代对象进行求和,如果需要对其某个特定属性的值求和的话可以设置attribute属性
三 自定义过滤器
1 ) template_global()
@app.template_global()
def sb(a1, a2):
return a1 + a2
全局调用
{{ sb(1, 9) }}
2) template_filter()
@app.template_filter()
def db(a1, a2, a3):
return a1 + a2 + a3
全局调用
{{ 1|db(2, 3) }}
四 自定义宏
{% macro ccc(name, type="text", value='') %}
自定义宏什么都显示
<input name="{{ name }}" type="{{ type }}" value="{{ value }}">
{% endmacro %}
正式调用宏,显示一个input 框
{{ ccc('n1','', 'xx') }}
一般会把宏写在一个单独的文件里
当宏作为一个单独文件时{% include 'xx' %} 要先引用
五 模板继承
模板继承block和extends:
- 语法:在父模板板中使用{% block block_name %}{% endblock %}进行模块的占位,block_name可以自己定义,其他的都是固定的语法格式;在子模板中使用{% extends "xxx.html" %}表示此HTML模板继承自“xxx.html”模板(父模板),然后在子模板中使用{% block block_name %} ... {% endblock %}重新定父模板中占位的block模块(注意子模板此时不用再写父模板中已有的内容,包括HTML标签),子模板中定义模块内容就会显示在母板中占位的位置,不同的子模板中可以定义不同的模块内容来满足自身的需要。
- 使用:{% extends "xxx.html" %}需要放在所有代码的前面,一般就放在第一行。还有另外一点就是子模板如果使用了继承,那么子模板中所有的代码就需要放在block中实现,也就是说想要实现一些没有在父模板block中的代码,那么就需要在父模板中再添加一个block进行占位了,不然在子模板中写在block之外的代码不会被展示出来。
- block:父模板的block中也可以写代码,当时如果子模板中重新定义了此block的内容,那么父模板此block就会被覆盖掉,当然如果没有重新定义,自然就还是展示父模板中的block内容。
- super:如果在子模板中的block中想要使用父模板中此block的内容,那么使用{{ super() }}就可以让父模板中block的内容“copy”这个位置了。
- self:如果想要在block中使用另一个block中的内容,可以使用{{ self.block_name() }}就可以让另一个block中的内容“copy”到这个位置。当然,如果子模板中重新定义了block的内容,那么self就会使用子模板中的block了。
关于super:
{% block header %}
{{ super() }}
..........
{% endblock %}
就是说原来的模板的header块里有内容, 用super继承可以在原内容的基础上接着扩展
六 在模板跳转和加载静态文件
1. 跳转
- <a href="/login/">点击我</a>
- <a href="{{ url_for('login_function') }}">点击我</a>
2.加载静态文件
- <link rel="stylesheet" href="static/css/index.css">
- <link rel="stylesheet" href="{{ url_for('static',filename=''css/index.css) }}"> filename 的值是文件的位置
七 set和with
set语句:类似Python的定义变量,在模板中使用形如{% set para_name=para_value %}就可以在这个语句之后使用这个变量了(在本模板中)。
with语句:使用形如{% with [para_name=para_value] %}...{% endwith %},如果这里定义了变量,那么这个变量就只能在with的作用域中使用了,也可以在with的作用域中使用set语句,那么set定义的变量也是只能在with作用域中生效。
八 is 关键字判断条件
利用is关键字和所谓的“测试方法”可以获得一个布尔值,从而利用其进行一些逻辑判断。比如{{ name is defined }}可以返回True/False来体现name这个变量是否被定义了。类似的“测试方法”还有:
- callable(object) 检查一个对象是否可调用
- defined/undefined(object) 检查一个对象是/否被定义了
- divisibleby(value,num) 检查value能否被数字num整除
- escaped(value) 检查一个对象是否被转码了
- iterable(value) 检查一个对象是否可迭代
- lower/upper(value) 检查一个对象是否都小/大写
- none(value) 检查一个对象是否是None
- number(value) 检查一个对象是否是数字
- sameas(value,other) 检查一个对象是否和other这个对象是同一个对象
用法:{% if loop.index is divisibleby(3) %}就表示如果loop.index这个值能够被3整除的话就进入这个逻辑分支
除了上面这些带参数的判断条件,也有一些不带参数的条件,在Jinja2里被称为测试器(test)。比如:
- defined/none 检查一个对象是否被定义,其实效果和{% if var %}是一样的
- upper/lower 检查一个字符串对象是否都是大写或小写
- string {% if var is string %}检查对象是不是一个字符串
- odd/even 检查一个整数对象是否是奇/偶数
- iterable 检查一个对象是不是可迭代对象,简单来说就是看是不是列表之类的序列类型
- mapping 检查一个对象是不是k-v对形式的对象,比如字典
九 自定义测试器
def over_five(string):
#接受的一定是一个字符串对象,然后可以在函数中对这个字符串做出处理
return int(string) > 5
app.add_template_test(over_five,'my_test')
'''
然后在模板中就可以这么用了:
{% if num is my_test %}
<p>{{ num }} is bigger than 5</p>
{% else %}
<p>{{ num }} is smaller than 5</p>
{% endif %}
'''
十 独立使用jinja
from jinja2 import Template
t = Template('Hello, {{ name }}')
print t.render(name='Frank')
# 输出 Hello, Frank