概述
一个模板其实就是一个普通的文本文件。它可以被设计为任何文本格式(HTML,XML,CSV等等)。它也不需要确定的扩展名,不过一般我们都会 用’.html’或’.xml’
模板语法的大量灵感来自于 Django 和 Python 。
- 模板包含 变量 或 表达式 ,这两者在模板求值的时候会被替换为值。
- 模板中 还有标签,控制模板的逻辑。
变量
可以传递python的变量给模板,用来替换其在模板中的“变量标记”。
note:“变量”和“变量标记”; “变量属性”、“修改变量”。
传入的变量可以是任何Python对象(并且是动态绑定)。———在模板中可以直接操作传入的变量对象,也可以完全访问这些变量的属性。
访问变量属性有两种方式
- “obj.attr”的方式
- 类似字典的方式:”obj[‘attr’]”
注意:{{ .. }}是Jinja的用来打印“变量标记”。如果要在其它标签中访问变量,则不能在变量名旁边加花括号。
过滤器(filters)
变量可以通过 过滤器 修改。
- 过滤器类似于管道操作:过滤器与变量之间用管道符号( | )分割
- 多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入
- 可以用圆括号传递可选参数,类似于函数调用
例如:
- {{ name|striptags|title }} : 移除变量中的Tag(name中的所有HTML标签)并且改写为标题样式的大小写格式。
- {{ list|join(‘, ‘) }} : 把一个列表用逗号连接起来。
检查器(tests)
检查器用来在Jinja的if块里面检查一个变量是否符合某种条件。它的用法是 varname is atest, 例如检查一个变量是否存在
检查器跟过滤器一样,也可以有参数,如果检查器只有一个参数,可以不写括号,直接用一个空格将检查器名和参数隔开,
注释
注释的标签:{# … #}
模板继承
Jinja 中最强大的部分就是模板继承————创建一个包含所有共同元素的页面基本骨架,并定义子模块中可以覆盖的 块 ,然后在子模板中重用这些公用的元素。
base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}base{% endblock %}.html</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
{% block body %} <h1> This is a base.html </h1>
<u> underline lable </u>
<u> underline lable </u>
{% endblock %}
<div id="footer">
{% block footer %}
© Copyright 2008 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
{% block .. %} .. {% endblock %} 标签 定义了四个子模板可以填充的块。所有的 block 标签告诉模板引擎子模板可以 覆盖(全部覆盖重写) 模板中的这些部分。
child.html
{% extends "base.html" %}
{% block title %}child{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
</p>
{% endblock %}
{% block body1 %}<h3>This is a child.html</h3>{% endblock %}
- {% extends %} 标签告诉模板引擎这个模板“继承”另一个模板。 当模板系统对这个模板求值时,首先定位父模板。
- extends 标签应该是模板中的第一个标签。
- 不能在同一个模板中定义多个同名的 {% block %} 标签。因为块标签以两种 方向工作,所以存在这种限制。即一个块标签不仅提供一个可以填充的部分,也在父级 定义填充的内容。如果同一个模板中有两个同名的 {% block %} 标签,父模板 无法获知要使用哪一个块的内容。
如果你想要多次打印一个块,无论如何你可以使用特殊的 self 变量并调用与块同名 的函数:
<title>{% block title %}{% endblock %}</title>
<h1>{{ self.title() }}</h1>
{% block body %}{% endblock %}