view genshi_view/template/+package+/handlers.py @ 21:807c8eef8098

add a handler for tempita; should rename the package (at some point) template_view
author Jeff Hammel <jhammel@mozilla.com>
date Wed, 17 Nov 2010 11:02:33 -0800
parents d54f85043f77
children
line wrap: on
line source

"""
request handlers:
these are instantiated for every request, then called
"""

import os
from pkg_resources import resource_filename
from urlparse import urlparse
from webob import Response, exc
from tempita import HTMLTemplate

class HandlerMatchException(Exception):
    """the handler doesn't match the request"""

class Handler(object):

    methods = set(['GET']) # methods to listen to
    handler_path = [] # path elements to match        

    @classmethod
    def match(cls, app, request):

        # check the method
        if request.method not in cls.methods:
            return None

        # check the path
        if request.environ['path'][:len(cls.handler_path)] != cls.handler_path:
            return None

        try:
            return cls(app, request)
        except HandlerMatchException:
            return None
    
    def __init__(self, app, request):
        self.app = app
        self.request = request
        self.application_path = urlparse(request.application_url)[2]

    def link(self, path=(), permanant=False):
        if isinstance(path, basestring):
            path = [ path ]
        path = [ i.strip('/') for i in path ]
        if permanant:
            application_url = [ self.request.application_url ]
        else:
            application_url = [ self.application_path ]
        path = application_url + path
        return '/'.join(path)

    def redirect(self, location):
        raise exc.HTTPSeeOther(location=location)

class TempitaHandler(Handler):

    template_dirs = [ resource_filename(__name__, 'templates') ]
    
    def __init__(self, app, request):
        Handler.__init__(self, app, request)
        self.data = { 'request': request,
                      'link': self.link }

    def __call__(self):
        return getattr(self, self.request.method.title())()

    def find_template(self, template):
        for d in self.template_dirs:
            path = os.path.join(d, template)
            if os.path.exists(path):
                return HTMLTemplate.from_filename(path)

    def Get(self):
        # needs to have self.template set
        template = self.find_template(self.template)
        return Response(content_type='text/html',
                        body=template.substitute(**self.data))


class GenshiHandler(Handler):

    def __init__(self, app, request):
        Handler.__init__(self, app, request)
        self.data = { 'request': request,
                      'link': self.link }

    def __call__(self):
        return getattr(self, self.request.method.title())()

    def Get(self):
        # needs to have self.template set
        template = self.app.loader.load(self.template)
        return Response(content_type='text/html',
                        body=template.generate(**self.data).render('html'))



class Index(GenshiHandler):
    template = 'index.html'
    methods=set(['GET', 'POST'])

    def __init__(self, app, request):
        GenshiHandler.__init__(self, app, request)

    def Get(self):
        self.data['name'] = self.request.remote_user or self.app.name
        return GenshiHandler.Get(self)

    def Post(self):
        self.app.name = self.request.POST.get('name', self.app.name)
        self.redirect(self.link(self.handler_path))