tornado模板
模板
- 模板使用,特别之处就是在Application多了个指定模板路径的参数,告诉Tornado在哪里寻找模板文件
app = tornado.web.Application(
handlers=[(r'/', IndexHandler), (r'/poem', PoemPageHandler)],
template_path=os.path.join(os.path.dirname(__file__), "templates")
)
- 模板语法
from tornado.template import Template
content = Template("<html><body><h1>{{ header }}</h1></body></html>")
print content.generate(header="Welcome!")
- 可以将任何Python表达式放在双大括号中
from tornado.template import Template
print Template("{{ 1+1 }}").generate()
print Template("{{ 'scrambled eggs'[-4:] }}").generate()
print Template("{{ ', '.join([str(x*x) for x in range(10)]) }}").generate()
模板中使用函数
- escape(s) 替换字符串s中的&、<、>为他们对应的HTML字符
- url_escape(s) 使用urllib.quote_plus替换字符串s中的字符为URL编码形式
- json_encode(val), 将val编码成JSON格式
- squeeze(s),过滤字符串s,把连续的多个空白字符替换成一个空格
模板传递函数
from tornado.template import Template
def disemvowel(s):
return ''.join([x for x in s if x not in 'efghi'])
print Template("my name is {{d('abcdefghijklmn')}}").generate(d=disemvowel)
# 输出: my name is abcdjklmn
- 静态资源目录指定和调试模式
app = tornado.web.Application(
handlers=[(r'/', IndexHandler), (r'/poem', MungedPageHandler)],
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True
)
# debug=True,它调用了一个便利的测试模式:tornado.autoreload模块,
# 此时,一旦主要的Python文件被修改,Tornado将会尝试重启服务器,并且在模板改变时会进行刷新。对于快速改变和实时更新这非常棒,
# 但不要再生产上使用它,因为它将防止Tornado缓存模板
- 模板中指定静态资源地址
<link rel="stylesheet" href="{{ static_url("style.css") }}">
会渲染输出: link rel="stylesheet" href="/static/style.css?v=ab12">
# v=ab12, hash值,staic_url的功能,防止缓存
模板扩展
- 扩展模板, 在新模板中重用一个已经有的main.html
{% extends "main.html" %}
- 覆写
父模块中:
<header>
{% block header %}{% end %}
</header>
子模块中覆写:
{% block header %}
<h1>Hello world!</h1>
{% end %}
- 使用application子类
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",
page_title = "Burt's Books | Home",
header_text = "Welcome to Burt's Books!",
)
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标签被自动转义成特殊符号,防止后端为数据库的网站被恶意脚本攻击
- 禁止自动转义, 当通过模板和模块提供HTML动态内容时,需要禁止自动转义
- 在Application构造函数中传递autoescape=None
- 在每页的基础上修改自动转义行为,这些autoescape块不需要结束标签,并且可以设置xhtml_escape来开启自动转义(默认行为),或None来关闭
{% autoescape None %}
{{ mailLink }}
- 指定为url,让其它地方保持自动转义
{% raw linkify("https://fb.me/burtsbooks", extra_params='ref=website') %}.
UI 模块
- UI模块是封装模板中包含的标记、样式以及行为的可复用组件。它所定义的元素通常用于多个模板交叉复用或在同一个模板中重复使用,{% module Foo(…) %}标签引用一个模块时,Tornado的模板引擎调用模块的render方法,然后返回一个字符串来替换模板中的模块标签
import tornado.web
import tornado.options
import os.path
from tornado.options import define, options
define("port", default=8003, 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}
)
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 Hello() %}
</body>
</html>