模板设计者文档
模板是文本文件,对于Jinja引擎来说,并不区分文本文件的扩展名。
Jinja模板的语法与Django和Python十分相似,主要包括遍历、表达式和标签等几类。
中文文档:http://www.ainoob.cn/docs/jinja2/templates.html
变量
{{ name }}
{{ student.name }}
{{ student['name'] }}
变量被替换成什么内容,完全取决于程序提供什么内容。如果变量未被定义,默认打印空字符串。
Jinja处理student.name和student['name']的方式有所差别:
.name优先检查student对象的属性,然后检查其项,都没查找到时返回未定义对象['name']优先检查student对象的项,然后检查其属性,都没查找到时返回未定义对象- 如果一个对象具有同名但不同值的属性和项,这个差异就非常重要
attr()过滤器只查找属性
过滤器
过滤器实际上就是一类特殊的函数。该函数以Jinja变量作为第一参数,返回一个新的值用于模板填充。
因此可以用管道符|来表示过滤器“修改”变量并填充新值的这一行为。
管道符可以串联多个过滤器,使用最后的结果填充模板。
{{ name|stringtags|title }}
{{ list|join(', ') }}
内置过滤器清单:http://www.ainoob.cn/docs/jinja2/templates.html#builtin-filters
abs(number)attr(object, name):类似于object.name,但是只查找对象的属性batch(value, linecount, fill_with=None):对序列进行分批capitalize(string):大写首字母,小写其他所有字母center(value, width=80):将值居中default(value, default='', boolean=false):为未定义的变量提供默认值,简写为ddictsort(_dict, case_sensitive=false, by='key')对字典进行排序escape(string):转义HTML中的特殊字符,例如&,<,>,',"filesizeformat(value, binary=false):文件大小数值的可视化first(seq)float(value, default=0.0)forceescape(value)format(value, *args, **kwargs):与Python的format函数相似groupby(objects, attribute):将对象序列按照指定属性分组indent(s, width=4, indentfirst=false):每一行缩进指定宽度,首行默认不缩进int(value, default=0, base=10)join(seq, sep='', attribute=none)last(seq)length(seq_or_map)list(value)lower(s)map(seq, other_filter)ormap(mapping, attribute)pprint(value, verbose=false):友好的打印random(seq):采样reject(objects, test):测试rejectattr(objects, attr, value?)replace(s, old, new, count=none)reverse(value)round(value, precision=0, method='common'):四舍五入safe(value):在自动转义的环境中不进行转义select(objects, test):选择selectattr(objects, attr, value?)slice(iterator, slices, fill_with=none)sort(iterable, reverse=false, case_sensitive=false, attribute=none)string(object)striptags(value):移除SGML/XML中的标签,并将相邻的空白改为一个空格sum(iterable, attribute=none, start=0)title(s)trim(s):移除首位的空白truncate(s, length=255, killwords=false, end='...'):截取字符串uper(s)urlencode(value)urlize(value, trim_url_limit=none, nofollow=false, target=none):可点击的文本wordcount(s):数单词wordwrap(s, ...)???xmlattr(...)???
测试
测试即检测某个值是否符合某个条件,实际上就是条件判断。
测试是一种语句,通过关键字is进行,例如{% loop.index is divisibleby(3) %}。
内置测试清单:http://www.ainoob.cn/docs/jinja2/templates.html#builtin-tests
callable对象是否可以被调用,例如函数、类definedorundefined是否被定义divisibleby是否能作为分母equalto(value, other)是否相等escaped是否被转义oddoreven奇偶iterable是否可迭代upperorlower大小写mapping是否是字典none是否为空number数值sameas(object, other)是否指向同一内存地址sequence序列string字符串
注释
{#
This is a comment.
#}
空白控制
默认情况下,模板引擎不会修改块中的空白(空格、制表符、换行符等)
……
转义
……
行语句
……
模板继承
在父模板中定义骨架,包括多个可被子模板覆盖的块。
……
HTML转义
……
控制
包括条件判断、循环、宏、块等。控制流的语法是{% ... %}。
for
遍历数组:
<ul>
{% for user in users %}
<li>{{ user.name|e }}</li>
{% endfor %}
</ul>
遍历字典:
<dl>
{% for key, value in some_dict.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
for循环中的特殊变量:
loop.index:当前循环迭代的次数,从1开始loop.index0:当前循环迭代的次数,从0开始loop.revindex:到循环结束还需要迭代的次数,从1开始loop.revindex0:到循环结束还需要迭代的次数,从0开始loop.first:是否是第一次迭代loop.last:是否是最后一次迭代loop.length:迭代的总次数loop.cycle:辅助函数
loop.cycle辅助函数
……
for ... if ...跳过循环
没有break或者continue语句跳出循环。作为替代,可以使用条件来跳过迭代:
{% for user in users if not user.hidden %}
<li>{{ user.name }}</li>
{% endfor %}
跳过的迭代不会计入循环的特殊变量中。
for ... else ...
如果没有进行有效的迭代,例如迭代序列为空,或者所有条目都被过滤掉了,就会执行else中的块:
<ul>
{% for user in users %}
<li>{{ user.name }}</li>
{% else %}
<li>no user found!</li>
{% endfor %}
</ul>
递归地使用循环
……
if
{% if kenny.sick %}
Kenny is sick.
{% elif kenny.dead %}
You killed Kenny! You bastard!!!
{% else %}
Kenny looks okay --- so far
{% endif %}
宏
……
调用
……
过滤器
{% filter upper %}
This text becomes uppercase
{% endfilter %}
赋值
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = call_something() %}
继承
……
块
……
包含
……
导入
……
导入上下文行为
……
表达式
字面量
"barwe"or'barwe'12or12.3["apple", "banana", "orange"](1,)or(1, 2, 3){"key": "value"}trueorfalsenone
算术
+, -, *, /, //, %, **
比较
==, !=, >, >=, <, <=
逻辑
and, or, not
is和in与not搭配时需要使用中缀记法:is not, not in
其他运算符
-
inornot in:左边是否包含于右边 -
isoris not:左边是否等于右边 -
|:应用一个过滤器 -
~:将所有操作数转换为字符串并连接它们,例如{% set name = "barwe" %} {% set age = 26 %} {{ "The age of " ~ name ~ " is " ~ age }} {# The age of barwe is 26 #} -
():调用宏、过滤器等 -
.or[]:获取对象的属性或者项
if表达式
内联的if表达式与Python相似:
{% extends layout_template if layout_template is defined else 'master.html' %}
不同的是,Python需要同时指定if和else,Jinja2可以不用指定else,此时返回一个未定义对象。
全局函数清单
range(stop)
range(start, stop)
range(start, stop, step)
整数列表lipsum(n=5, html=true, min=20, max=100)???dict(**items)字典字面量class cycler(*items)周期,更像是生成器,但是可以回退.reset()重置到第一个.next()返回当前项并跳转到下一个.current返回当前项
class joiner(sep=',')???
扩展
i18n
……
表达式语句
加载表达式语句扩展,使用不打印的表达式:
{% do some_seq.append('something') %}
循环控制
启用 break 和 continue:
{% for user in users %}
{% if loop.index is even %}
{% continue %}
{% endif %}
{% endfor %}
with语句
设置一个内作用域,该作用域内定义的变量对作用域外不可见:
{% with %}
{% set name = "barwe" %}
{{ name }} name is "barwe"
{% endwith %}
自动转义
{% autoescape true %}
...
{% endautoescape %}
评论区