Tornado使用mako 模板總結

import tornado.web
import tornado.ioloop
import tornado.auth
import tornado.escape
import tornado.options

from tornado.options import define, options

import mako.lookup
import mako.template

import os

define('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模板提供的一些功能.
相關文章
相關標籤/搜索