-
Notifications
You must be signed in to change notification settings - Fork 0
Description
jinja2 模板
模板仅仅是文本文件。它可以生成任何基于文本的格式(HTML、XML、CSV、LaTex 等等)。 它并没有特定的扩展名, .html 或 .xml 都是可以的。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
</body>
</html>这包含了默认的设定。应用开发者也会把语法从 {% foo %} 改成 <% foo %> 或类似的东西。
这里有两种分隔符: {% ... %} 和 {{ ... }} 。前者用于执行诸如 for 循环 或赋值的语句,后者把表达式的结果打印到模板上。
变量
应用把变量传递到模板,你可能在模板中弄混。变量上面也可以有你能访问的属性或元 素。变量看起来是什么,完全取决于应用提供了什么。
你可以使用点( . )来访问变量的属性,作为替代,也可以使用所谓的“下标”语 法( [] )。下面的几行效果是一样的:
{{ foo.bar }}
{{ foo['bar'] }}重要
实现
为方便起见,Jinja2 中 foo.bar 在 Python 层中做下面的事情:
检查 foo 上是否有一个名为 bar 的属性。
如果没有,检查 foo 中是否有一个 'bar' 项 。
如果没有,返回一个未定义对象。
foo['bar'] 的方式相反,只在顺序上有细小差异:
检查在 foo 中是否有一个 'bar' 项。
如果没有,检查 foo 上是否有一个名为 bar 的属性。
如果没有,返回一个未定义对象。
如果一个对象有同名的项和属性,这很重要。此外,有一个 attr() 过滤 器,它只查找属性。
过滤器
变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为 后一个过滤器的输入。
例如 {{ name|striptags|title }} 会移除 name 中的所有 HTML 标签并且改写 为标题样式的大小写格式。过滤器接受带圆括号的参数,如同函数调用。这个例子会 把一个列表用逗号连接起来:{{ list|join(', ') }}。
测试
除了过滤器,所谓的“测试”也是可用的。测试可以用于对照普通表达式测试一个变量。 要测试一个变量或表达式,你要在变量后加上一个 is 以及测试的名称。例如,要得出 一个值是否定义过,你可以用 name is defined ,这会根据 name 是否定义返回 true 或 false 。
测试也可以接受参数。如果测试只接受一个参数,你可以省去括号来分组它们。例如, 下面的两个表达式做同样的事情:
{% if loop.index is divisibleby 3 %}
{% if loop.index is divisibleby(3) %}注释
要把模板中一行的部分注释掉,默认使用 {# ... #} 注释语法。这在调试或 添加给你自己或其它模板设计者的信息时是有用的:
{# note: disabled template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}空白控制
默认配置中,模板引擎不会对空白做进一步修改,所以每个空白(空格、制表符、换行符 等等)都会原封不动返回。如果应用配置了 Jinja 的 trim_blocks ,模板标签后的 第一个换行符会被自动移除(像 PHP 中一样)。
此外,你也可以手动剥离模板中的空白。当你在块(比如一个 for 标签、一段注释或变 量表达式)的开始或结束放置一个减号( - ),可以移除块前或块后的空白:
{% for item in seq -%}
{{ item }}
{%- endfor %}这会产出中间不带空白的所有元素。如果 seq 是 1 到 9 的数字的列表, 输出会是 123456789 。
转义
有时想要或甚至必要让 Jinja 忽略部分,不会把它作为变量或块来处理。例如,如果 使用默认语法,你想在在使用把 {{ 作为原始字符串使用,并且不会开始一个变量 的语法结构,你需要使用一个技巧。最简单的方法是在变量分隔符中( {{ )使用变量表达式输出:
对于较大的段落,标记一个块为 raw 是有意义的。例如展示 Jinja 语法的实例, 你可以在模板中用这个片段:
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}行语句
如果应用启用了行语句,就可以把一个行标记为一个语句。例如如果行语句前缀配置为 # ,下面的两个例子是等价的:
<ul>
# for item in seq
<li>{{ item }}</li>
# endfor
</ul>
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>行语句前缀可以出现在一行的任意位置,只要它前面没有文本。为了语句有更好的可读 性,在块的开始(比如 for 、 if 、 elif 等等)以冒号结尾:
# for item in seq:
...
# endfor提示
若有未闭合的圆括号、花括号或方括号,行语句可以跨越多行:
<ul>
# for href, caption in [('index.html', 'Index'),
('about.html', 'About')]:
<li><a href="{{ href }}">{{ caption }}</a></li>
# endfor
</ul>从 Jinja 2.2 开始,行注释也可以使用了。例如如果配置 ## 为行注释前缀, 行中所有 ## 之后的内容(不包括换行符)会被忽略:
# for item in seq:
<li>{{ item }}</li> ## this comment is ignored
# endfor模板继承
Jinja 中最强大的部分就是模板继承。模板继承允许你构建一个包含你站点共同元素的基 本模板“骨架”,并定义子模板可以覆盖的 块 。
基本模板
这个模板,我们会把它叫做 base.html ,定义了一个简单的 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 %}{% 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在本例中, {% block %} 标签定义了四个字幕版可以填充的块。所有的 block 标签 告诉模板引擎子模板可以覆盖模板中的这些部分。
子模板
{% extends "base.html" %}
{% block title %}Index{% 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 %}{% extend %} 标签是这里的关键。它告诉模板引擎这个模板“继承”另一个模板。 当模板系统对这个模板求值时,首先定位父模板。 extends 标签应该是模板中的第一个 标签。它前面的所有东西都会按照普通情况打印出来,而且可能会导致一些困惑
模板的文件名依赖于模板加载器。例如 FileSystemLoader 允许你用文件名访 问其它模板。你可以使用斜线访问子目录中的模板:
{% extends "layout/default.html" %}Super 块
可以调用 super 来渲染父级块的内容。这会返回父级块的结果:
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ super() }}
{% endblock %}命名块结束标签
Jinja2 允许你在块的结束标签中加入的名称来改善可读性:
{% block sidebar %}
{% block inner_sidebar %}
...
{% endblock inner_sidebar %}
{% endblock sidebar %}无论如何, endblock 后面的名称一定与块名匹配。
嵌套块和作用域
嵌套块可以胜任更复杂的布局。而默认的块不允许访问块外作用域中的变量:
{% for item in seq %}
<li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}模板对象
HTML 转义
使用手动转义
控制结构清单
...................
模板设计者文档