jinja2模板设计三:模板继续
模板继承
Jinja 中最强大的部分就是模板继承。模板继承允许你构建一个包含你站点共同元素的基 本模板“骨架”,并定义子模板可以覆盖的 块 。
听起来复杂,实际上很简单。从例子上手是最易于理解的。
1.基本模板
这个模板,我们会把它叫做 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 标签 告诉模板引擎子模板可以覆盖模板中的这些部分。
2.子模板
一个子模板看起来是这样:
{% 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" %}
这种行为也可能依赖于应用内嵌的 Jinja 。注意子模板没有定义 footer 块,会 使用父模板中的值。
你不能在同一个模板中定义多个同名的 {% block %} 标签。
因为块标签以两种 方向工作,所以存在这种限制。
即一个块标签不仅提供一个可以填充的部分,也在父级 定义填充的内容。
如果同一个模板中有两个同名的 {% blok %} 标签,父模板 无法获知要使用哪一个块的内容。
如果你想要多次打印一个块,无论如何你可以使用特殊的 self 变量并调用与块同名 的函数:
<title>{% block title %}{% endblock %}</title> <h1>{{ self.title() }}</h1> {% block body %}{% endblock %}
3.Super 块
可以调用 super 来渲染父级块的内容。这会返回父级块的结果:
即{{super()}}部分,将继承父级块的内容
{% block sidebar %} <h3>Table Of Contents</h3> ... {{ super() }} {% endblock %}
4.命名块结束标签
Jinja2 允许你在块的结束标签中加入的名称来改善可读性:
{% block sidebar %}
{% block inner_sidebar %}
...
{% endblock inner_sidebar %}
{% endblock sidebar %}
无论如何, endblock 后面的名称一定与块名匹配。
5.嵌套块和作用域¶
嵌套块可以胜任更复杂的布局。而默认的块不允许访问块外作用域中的变量:
{% for item in seq %} <li>{% block loop_item %}{{ item }}{% endblock %}</li> {% endfor %}
这个例子会输出空的 <li> 项,因为 item 在块中是不可用的。其原因是,如果 块被子模板替换,变量在其块中可能是未定义的或未被传递到上下文。
从 Jinja 2.2 开始,你可以显式地指定在块中可用的变量,只需在块声明中添加 scoped修饰,就把块设定到作用域中:
{% for item in seq %} <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li> {% endfor %}
当覆盖一个块时,不需要提供 scoped 修饰。
6.模板对象
当一个模板对象被传递到模板上下文,你也可以从那个对象继承。假设调用 代码传递 layout_template 布局模板到环境,这段代码会工作:
{% extends layout_template %}
之前 layout_template 变量一定是布局模板文件名的字符串才能工作。
posted on 2015-08-04 17:08 myworldworld 阅读(223) 评论(0) 收藏 举报