模板继承
语法:{% extends "filename.html" %}
块,block语句
语法:{% block header %}{% end %}
main.html
<html>
<body>
<header>
{% block header %}{% end %}
</header>
<content>
{% block body %}{% end %}
</content>
<footer>
{% block footer %}this footer{% end %}
</footer>
</body>
</html>
index.html
继承自main.html
,各个部分插入到main.html
中相应的代码块。
{% extends "main.html" %}
{% block header %}
<h1>{{ header_text }}</h1>
{% end %}
{% block body %}
<p>Hello from the child template!</p>
{% end %}
<!--如果不填写footer块将使用父模板的footer内容。-->
{% block footer %}
<p>{{ footer_text }}</p>
{% end %}
注意:没有闭合的{% block %}语句可以使得浏览器直接显示500: Internal Server Error,建议开启debug模式引发完整的Python堆栈跟踪
#完整代码
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.options
import os.path
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", MainHandler),
]
settings = dict(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True,
)
tornado.web.Application.__init__(self, handlers, **settings)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render(
"index.html",
header_text = "this header content",
footer_text = "this footer content",
)
if __name__ == "__main__":
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
自动转义
Tornado默认会自动转义模板中的内容,把标签转换为相应的HTML实体。这样可以防止后端为数据库的网站被恶意脚本攻击。
自动转义的好处:防止恶意脚本攻击。
自动转义的坏处:用户设置的链接被自动转义无法使用等,如
设置变量等于一个链接:{% set mailLink = "<a href="mailto:contact@burtsbooks.com">Contact Us</a>" %}
显示变量:{{ mailLink }}
自动转移后链接:<a href="mailto:contact@burtsbooks.com">Contact Us</a>
禁用自动转义
构造函数禁用(所有页面都禁用)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", MainHandler),
autoescape=None
]
settings = dict(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True,
)
tornado.web.Application.__init__(self, handlers, **settings)
在某一页面禁用:
{% set mailLink = "<a href="mailto:contact@burtsbooks.com">Contact Us</a>" %}
{% autoescape None %}
{{ mailLink }}
更简便的方法————可以使用{% raw %}指令来输出不转义的内容。
如:{% raw mailLink %}
UI模块
UI模块是封装模板中包含的标记、样式以及行为的可复用组件。它所定义的元素通常用于多个模板交叉复用或在同一个模板中重复使用。模块本身是一个继承自Tornado的UIModule类的简单Python类,并定义了一个render方法。当一个模板使用{% module Foo(...) %}标签引用一个模块时,Tornado的模板引擎调用模块的render方法,然后返回一个字符串来替换模板中的模块标签。UI模块也可以在渲染后的页面中嵌入自己的JavaScript和CSS文件,或指定额外包含的JavaScript或CSS文件。你可以定义可选的embedded_javascript、embedded_css、javascript_files和css_files方法来实现这一方法。
简单的说,UI模块是抽象出来通用的功能方法组成一个类,供继承使用,是复用组件。
#简单使用
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.options
import os.path
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.render('hello.html')
class HelloModule(tornado.web.UIModule):
def render(self):
return '<h1>Hello, world!</h1>'
if __name__ == '__main__':
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[(r'/', HelloHandler)],
template_path=os.path.join(os.path.dirname(__file__), 'templates'),
ui_modules={'Hello': HelloModule} #字典形式
#把名为Hello的模块的引用和定义的HelloModule类结合起来。
)
server = tornado.httpserver.HTTPServer(app)
server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
hello.html
<html>
<head><title>UI Module Example</title></head>
<body>
<!-- 使用方法 {% module 名字() %} -->
{% module Hello() %}
</body>
</html>
嵌入完整的文件js和css文件,可以是本地的也可以是外部的
javascript_files()
外部js文件
def javascript_files(self):
return "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"
css_files(self)
本地css
def css_files(self):
return "/static/css/newreleases.css"