pvl/verkko/web.py
author Tero Marttila <terom@paivola.fi>
Wed, 24 Oct 2012 18:10:42 +0300
changeset 24 45382e1c0be0
parent 16 51509b5ce1c0
child 26 589249097230
permissions -rw-r--r--
pvl.verkko.web: <script> support; returning response from process()
# encoding: utf-8

def merge (*dicts) :
    dict = {}

    for d in dicts :
        dict.update(d)

    return dict

# response types
from werkzeug.wrappers import Response
from werkzeug.exceptions import (
        HTTPException, 
        BadRequest,         # 400
        NotFound,           # 404
)
from werkzeug.utils import redirect

# view
from pvl.html import tags as html

class Handler (object) :
    """
        Per-Request controller/view, containing the request context and generating the response.
    """

    TITLE = None
    CSS = (
        #"/static/layout.css", 
        "/static/style.css", 
    )
    JS = (
        #"/static/jquery/jquery.js"
    )

    def __init__ (self, app, request, urls, params) :
        """
            app     - wsgi.Application
            request - werkzeug.Request
            urls    - werkzeug.routing.MapAdapter
        """

        self.app = app
        self.request = request
        self.urlmap = urls
        self.params = params
        
        # new ORM session per request
        self.db = app.db.session() 

    def url (self, handler=None, **params) :
        """
            Return an URL for given endpoint, with parameters,
        """

        if not handler :
            # XXX: just generate a plain-relative '?foo=...' url instead?
            handler = self.__class__
            params = merge(self.params, params)

        return self.urlmap.build(handler, params)
        
    def title (self) :
        """
            Render site/page title as text.
        """
        
        if self.TITLE :
            return u"Päivölä Verkko :: {title}".format(title=self.TITLE)
        else :
            return u"Päivölä Verkko"

    def render (self) :
        """
            Render page content (as <body>...</body>).
        """

        raise NotImplementedError()

    def render_html (self) :
        """
            Render page layout (as <html>).
        """

        title = self.title()

        return html.html(
            html.head(
                html.title(title),
                (
                    html.link(rel='Stylesheet', type="text/css", href=src) for src in self.CSS
                ), 
                (
                    html.script(src=src, type='text/javascript', _selfclosing=False) for src in self.JS
                ),
            ),
            html.body(
                html.h1(title),
                self.render() 
            )
        )

    def process (self, **params) :
        """
            Process request args to build internal request state.
        """

        pass

    def respond (self) :
        """
            Generate a response, or raise an HTTPException

            Does an HTML layout'd response per default.
        """
        
        # returning e.g. redirect?
        response = self.process(**self.params)

        if response :
            return response
        
        # render as html per default
        render = self.render_html()
        text = unicode(html.document(render))

        return Response(text, mimetype='text/html')