Jinjia2
语法
- 控制结构 {% %}
- 变量取值 {{ }}
- 注释 {# #}
变量
- 读取变量
{{ parameter }} - 读取字典
{{ parameter[‘key’] }}
{{ parameter.key }} - 读取数组
{{ parameter[3] }} - 读取对象
{{ object.something() }}
过滤器
变量可以通过“过滤器”进行修改,过滤器可以理解为是Jinja2里面的内置函数和字符串处理函数。
常用过滤器如下:
- abs(value):返回一个数值的绝对值。示例:-1|abs
- default(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|first
- format(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):计算一个长字符串中单词的个数。
示例
@ 字符串操作
{# 输出大写 #}
hello {{ name|upper }}!
{# 输出大写,超过3个字符打断,用'...'替代 #}
<h1>hello {{ name|upper|truncate(3,True) }}</h1>
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
{{ name | default('No name', true) }}
{# 单词首字母大写 #}
{{ 'hello' | capitalize }}
{# 单词全小写 #}
{{ 'XML' | lower }}
{# 去除字符串前后的空白字符 #}
{{ ' hello ' | trim }}
{# 字符串反转,返回"olleh" #}
{{ 'hello' | reverse }}
{# 格式化输出,返回"Number is 2" #}
{{ '%s is %d' | format("Number", 2) }}
{# 关闭HTML自动转义 #}
{{ '<em>name</em>' | safe }}
{% autoescape false %}
{# HTML转义,即使autoescape关了也转义,可以缩写为e #}
{{ '<em>name</em>' | escape }}
{% endautoescape %}
@ 数值操作
{# 四舍五入取整,返回13.0 #}
{{ 12.8888 | round }}
{# 向下截取到小数点后2位,返回12.88 #}
{{ 12.8888 | round(2, 'floor') }}
{# 绝对值,返回12 #}
{{ -12 | abs }}
@ 列表操作
{# 取第一个元素 #}
{{ [1,2,3,4,5] | first }}
{# 取最后一个元素 #}
{{ [1,2,3,4,5] | last }}
{# 返回列表长度,可以写为count #}
{{ [1,2,3,4,5] | length }}
{# 列表求和 #}
{{ [1,2,3,4,5] | sum }}
{# 列表排序,默认为升序 #}
{{ [3,2,1,5,4] | sort }}
{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
{{ [1,2,3,4,5] | join(' | ') }}
{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
{{ ['tom','bob','ada'] | upper }}
@ 字典操作
{% set users=[{'name':'Tom','gender':'M','age':20},
{'name':'John','gender':'M','age':18},
{'name':'Mary','gender':'F','age':24},
{'name':'Bob','gender':'M','age':31},
{'name':'Lisa','gender':'F','age':19}]
%}
{# 按指定字段排序,这里设reverse为true使其按降序排 #}
<ul>
{% for user in users | sort(attribute='age', reverse=true) %}
<li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>
{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
<ul>
{% for group in users|groupby('gender') %}
<li>{{ group.grouper }}
<ul>
{% for user in group.list %}
<li>{{ user.name }}</li>
{% endfor %}</ul>
</li>
{% endfor %}
</ul>
{# 取字典中的某一项组成列表,再将其连接起来 #}
{{ users | map(attribute='name') | join(', ') }}
jinja2的控制结构
jinja2中的if语句类似与Python的if语句,它也具有单分支,多分支等多种结构,不同的是,条件语句不需要使用冒号结尾,而结束控制语句,需要使用endif关键字。
{% if daxin.safe %}
daxin is safe.
{% elif daxin.dead %}
daxin is dead
{% else %}
daxin is okay
{% endif %}
jinja2的for循环
jinja2中的for循环用于迭代Python的数据类型,包括列表,元组和字典。在jinja2中不存在while循环。
基本语法
- 迭代列表
<ul>
{% for user in users %}
<li>{{ user.username|title }}</li>
{% endfor %}
</ul>
- 迭代字典
<dl>
{% for key, value in my_dict.iteritems() %}
<dt>{{ key }}</dt>
<dd>{{ value}}</dd>
{% endfor %}
</dl>
for循环中的特殊变量
变量 | 描述 |
---|---|
loop.index | 当前迭代的索引(从1开始) |
loop.index0 | 当前迭代的索引(从0开始) |
loop.first | 是否是第一次迭代,返回bool |
loop.last | 是否是最后一次迭代,返回bool |
loop.length | 序列中的项目数量 |
loop.revindex | 到循环结束的次数(从1开始) |
loop.revindex0 | 到循环结束的次数(从0开始) |
宏(类似函数)
宏类似于Python中的函数,我们在宏中定义行为,还可以进行传递参数,就像Python中的函数一样一样儿的。
定义:在宏中定义一个宏的关键字是macro,后面跟其 宏的名称和参数等
{% macro input(name,age=18) %} # 参数age的默认值为18
<input type='text' name="{{ name }}" value="{{ age }}" >
{% endmacro %}
调用:调用方法也和Python的类似
<p>{{ input('daxin') }} </p>
<p>{{ input('daxin',age=20) }} </p>
jinja2的继承和Super函数
jinja2中最强大的部分就是模板继承。模板继承允许我们创建一个基本(骨架)文件,其他文件从该骨架文件继承,然后针对自己需要的地方进行修改。
jinja2的骨架文件中,利用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 %}
<script>This is javascript code </script>
{% endblock %}
</div>
</body>
</html>
子:
这里定义了四处 block,即:head,title,content,footer。那怎么进行继承和变量替换呢?注意看下面的文件
{% extend "base.html" %} # 继承base.html文件
{% block title %} Dachenzi {% endblock %} # 定制title部分的内容
{% block head %}
{{ super() }} # 用于获取原有的信息
<style type='text/css'>
.important { color: #FFFFFF }
</style>
{% endblock %}
PS: super()函数 表示获取block块中定义的原来的内容。
渲染
jinja2模块中有一个名为Enviroment的类,这个类的实例用于存储配置和全局对象,然后从文件系统或其他位置中加载模板。
基本使用方法
大多数应用都在初始化的时候撞见一个Environment对象,并用它加载模板。Environment支持两种加载方式:
- PackageLoader:包加载器
- FileSystemLoader:文件系统加载器
PackageLoader
使用包加载器来加载文档的最简单的方式如下:
from jinja2 import PackageLoader,Environment
env = Environment(loader=PackageLoader('python_project','templates')) # 创建一个包加载器对象
template = env.get_template('bast.html') # 获取一个模板文件
template.render(name='daxin',age=18) # 渲染
其中:
- PackageLoader()的两个参数为:python包的名称,以及模板目录名称。
- get_template():获取模板目录下的某个具体文件。
- render():接受变量,对模板进行渲染
FileSystemLoader
文件系统加载器,不需要模板文件存在某个Python包下,可以直接访问系统中的文件。