本文发自 http://www.binss.me/blog/record-of-learning-tornado-3-template-extension/,转载请注明出处。
为了避免书写重复前端代码,提高前端代码的复用性,Tornado使用了模版拓展和模块两种机制来实现这个目的。
模版拓展
先写一个父模版base.html:
<html>
<head>
<title>mysite</title>
</head>
<body>
<header>
{% block header %}{% end %}
</header>
<content>
{% block body %}{% end %}
</content>
<footer>
{% block footer %}{% end %}
</footer>
</body>
</html>
子模版page_1.html可以通过拓展父模版实现其自身页面:
{% extends "base.html" %}
{% block header %}
<h1>page_1</h1>
{% end %}
{% block body %}
<p>Hello from the child template!</p>
{% end %}
{% block footer %}
<p>page_1</p>
{% end %}
其做法是将父模版的所有内容复制进来,然后用 {% block 块名 %}{% end %}
包含的内容去替换父模版中相应的块。如果还有类似的页面page_2,那么只需按相同的块替换方法对base.html进行拓展即可。这种做法大大减少了前端重复代码量。
注意:一个语法错误或者没有闭合的 {% block %}
语句可以使得浏览器直接显示500: Internal Server Error。
模块
用于封装模板中包含的标记、样式以及行为,以便在同一模版或多个模版之间重复使用。
先定义html文件:modules/hello.html
<h1>Hello, {{ name }}</h1>
再定义控制器:
class HelloModule(tornado.web.UIModule):
def render(self, name):
return self.render_string('modules/hello.html', name=name)
还要在Application的settings字典中加 ui_modules={'Hello': HelloModule}
以声明模块。
定义了模块后,我们就可以在其他模版中引用它:如在index.html中加入:
{% for name in names %}
{% module Hello(name) %}
{% end %}
index模版的控制器改为:
[python]
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html',names=["dudu", "niang"])
访问后显示如下:
Hello, dudu
Hello, niang
这是因为在模版index.html中循环调用了两次Hello模块,根据传入的参数name生成了对应的句子并插入到模版中。这种做法亦减少了前端重复代码量,比起模版来,它更加灵活。
此外,Tornado还允许使用embedded_css和embedded_javascript方法嵌入其他的CSS和JavaScript来改变模块内容和样式。如:
class HelloModule(tornado.web.UIModule):
def render(self, name):
return self.render_string('modules/hello.html', name=name)
def embedded_css(self):
return ".name {background-color:#F5F5F5}"
def embedded_javascript(self):
return "document.write(\"hi!\")"
也可以通过以下函数直接嵌入文件:
def css_files(self):
return "/static/css/name.css"
def javascript_files(self):
return "/static/js/name.js"
还可以嵌入html代码:
def html_body(self):
return "<div class="addition"><p>html_body()</p></div>"
总而言之,Tornado通过模版拓展和模块两种机制,减少了前端的重复代码,使代码更加整洁美观。如果你是学完Django再来学Tornado,那么你会对两者在模版方面高度的相似性而感到惊叹。