import tornado.webimport tornado.ioloopimport tornado.authimport tornado.escapeimport tornado.optionsfrom tornado.options import define, optionsimport mako.lookupimport mako.templateimport osdefine('port', default=8888, help='run on given port', type=int)CURRENT_PATH= os.path.dirname(__file__)TEMPLATE_PATH = os.path.join(CURRENT_PATH, 'templates')STATIC_PATH = os.path.join(CURRENT_PATH, 'static')LOOK_UP = mako.lookup.TemplateLookup(directories=[TEMPLATE_PATH,], module_directory='/tmp/mako', output_encoding='utf-8', encoding_errors='replace')class Application(tornado.web.Application): def __init__(self): handlers = [ (r'/', MainHandler), ] settings = { 'cookie_secret':'', 'login_url':'', 'static_path':STATIC_PATH, 'xsrf_cookies':True, } super(Application, self).__init__(handlers, **settings)class BaseHandler(tornado.web.RequestHandler): def initialize(self, lookup=LOOK_UP): ''' Set template lookup object, Defalut is LOOK_UP ''' self._lookup = lookup def get_current_user(self): user = self.get_secure_cookie('user') if not user: return return tornado.escape.json_decode(user) def render_string(self, filename, **kwargs): ''' Override render_string to use mako template. Like tornado render_string method, this method also pass request handler environment to template engin. ''' try: template = self._loolup.get_template(filename) env_kwargs = dict( handler = self, request = self.request, current_user = self.current_user, locale = self.locale, _ = self.locale.translate, static_url = self.static_url, xsrf_form_html = self.xsrf_form_html, reverse_url = self.application.reverse_url, ) env_kwargs.update(kwargs) return template.render(**env_kwargs) except: # exception handler pass def render(self, filename, **kwargs): self.finish(self.render_string(filename, **kwargs))class MainHandler(BaseHandler): @tornado.web.authenticated def get(self): self.render('index.html', messages=[])class AuthLoginHandler(BaseHandler, tornado.web.GoogleMixin): @tornado.web.asynchronous def get(self): if self.get_argument('openid.mode', None): self.get_authenticated_user(self.async_callback(self._on_auth)) return self.authenticate.redirect() def _on_auth(self, user): if not user: raise tornado.web.HTTPError(500, 'Google authenticate failed') self.set_secure_cookie('user', tornado.escape.json_encode(user)) self.redirect('/')def main(): tornado.options.parse_command_line() app = Application() app.listen(options.port) tornado.ioloop.IOLoop.instance().start()if __name__ == '__main__': main()
如上代码所示,只需要在派生的BaseHandler override initilize 和 render_string即可. 其他Request handler只要
继承自BaseHandler即可.这样就不仅可以使用性能高效的mako模板,而且还能使用tornado模板提供的一些功能.