Fix up PageHandler.render to PageHandler.render_content, add PageHandler.process, and fix up orders
authorTero Marttila <terom@fixme.fi>
Thu, 23 Dec 2010 01:07:42 +0200
changeset 10 4bdb45071c89
parent 9 0327b83959e9
child 11 90a3c570c227
Fix up PageHandler.render to PageHandler.render_content, add PageHandler.process, and fix up orders
svv/controllers.py
svv/customers.py
svv/orders.py
--- a/svv/controllers.py	Thu Dec 23 00:57:46 2010 +0200
+++ b/svv/controllers.py	Thu Dec 23 01:07:42 2010 +0200
@@ -5,6 +5,7 @@
     respond(Request) -> Response
 """
 
+import werkzeug
 from werkzeug import Response
 
 from svv import html, pdf
@@ -30,13 +31,20 @@
         self.request = request
         self.urlmap = urlmap
 
-    def build_url (self, endpoint, **values) :
+    def url_for (self, endpoint, **values) :
         """
-            Return an URL for the given endpoint, applying the given values
+            Return an URL for the given endpoint, applying the given URL-embedded values
         """
 
         return self.urlmap.build(endpoint, values)
 
+    def redirect_for (self, endpoint, **values) :
+        """
+            Return a Response that will redirect the client to the given endpoint.
+        """
+
+        return werkzeug.redirect(self.url_for(endpoint, **values))
+
     @property
     def POST (self) :
         """
@@ -60,7 +68,21 @@
         Renders the layout template and HTML.
     """
 
-    def respond (self, url_values) :
+    def render_content (self, **args) :
+        """
+            Render and return HTML for page content.
+
+            XXX: must be HTML object, support just text?
+        """
+
+        raise NotImplementedError()
+
+    def render_layout (self, content) :
+        """
+            Render the page layout for the given content block.
+        """
+
+        # XXX: layout template, should be somewhere far away
         title = "Index"
         css = [
                 "/static/layout.css", 
@@ -97,16 +119,13 @@
         header = ("Foo List")
         nav = [tags.ul(tags.li(tags.a(href='#')(name)) for name in ['Nav A', 'Nav B', 'Nav C'])]
         menu = [tags.ul(tags.li(tags.a(href=url)(name)) for name, url in [
-            ("Etusivu",     self.build_url(urls.Index)),
-            ("Uusi tilaus", self.build_url(urls.NewOrderView)),
-            ("Tilaukset",   self.build_url(urls.OrdersView)),
-            ("Tilaajat",    self.build_url(urls.CustomersView)),
+            ("Etusivu",     self.url_for(urls.Index)),
+            ("Uusi tilaus", self.url_for(urls.NewOrderView)),
+            ("Tilaukset",   self.url_for(urls.OrdersView)),
+            ("Tilaajat",    self.url_for(urls.CustomersView)),
         ])]
         footer = ("Copyright?")
 
-        # render page HTML
-        content = self.render(**url_values)
-        
         layout = (
             tags.div(id='header')(header),
             tags.div(id='container')(
@@ -124,16 +143,41 @@
         # XXX: unicode?
         return Response(html_text, mimetype='text/html')
 
-    def render (self, **args) :
+    def render (self, **url_values) :
         """
-            Render and return HTML for page content.
-
-            XXX: must be HTML object, support just text?
+            Render full page HTML
         """
 
-        raise NotImplementedError()
+        # render page content
+        content = self.render_content(**url_values)
 
+        # render into layout
+        response = self.render_layout(content)
 
+        # ok
+        return response
+
+    def respond (self, url_values) :
+        response = None
+
+        if self.request.form :
+            # process POST data for e.g. redirect
+            response = self.process(**url_values)
+
+        if not response :
+            # render page HTML
+            response = self.render(**url_values)
+
+        # ok
+        return response
+
+    def process (self, **args) :
+        """
+            Process incoming POST data, optionally returning a redirect response.
+        """
+        
+        # default to ignore
+        pass
 
 ### XXX: random test controllers
 
@@ -226,7 +270,7 @@
         ]),
     )
 
-    def render (self) :
+    def render_content (self) :
         # build data set
         data = self.DATA
 
--- a/svv/customers.py	Thu Dec 23 00:57:46 2010 +0200
+++ b/svv/customers.py	Thu Dec 23 01:07:42 2010 +0200
@@ -13,7 +13,7 @@
         Page for main 'customers' view
     """
 
-    def render (self) :
+    def render_content (self) :
         # database
         conn = self.app.get_connection()
 
@@ -64,7 +64,7 @@
         )
 
 class CustomerView (PageHandler) :
-    def render (self, id) :
+    def render_content (self, id) :
         return tags.h1("Info for customer #%d" % id)
 
 
--- a/svv/orders.py	Thu Dec 23 00:57:46 2010 +0200
+++ b/svv/orders.py	Thu Dec 23 01:07:42 2010 +0200
@@ -333,6 +333,20 @@
             ) for opt_value, opt_title in options
         )
 
+    def render_datetime_input (self, name, value=None) :
+        """
+            Render HTML for a generic datetime control (using jQuery).
+
+                name            - field name, as used for POST
+                value           - selected date
+        """
+            
+        return (
+            self.render_text_input(name, (value.strftime(self.DATETIME_FORMAT) if value else None)),
+
+            tags.script("$(document).ready(function () { $('#" + name + "').datetimepicker(); });"),
+        )
+
     def render_customer_input (self) :
         """
             Render HTML for customer_id/name field inputs.
@@ -353,10 +367,10 @@
             Render HTML for contact name field <input>s
         """
         # recommended contacts for selected customer, if known
-        contacts = self.get_contact_list(self.customer_id)
+        contacts = self.build_contact_list(self.customer_id)
 
         return (
-            self.render_select_input('contact_id', ((id, name) for id, name, phone, email in contacts), self.contact_id)
+            self.render_select_input('contact_id', ((id, name) for id, name, phone, email in contacts), self.contact_id),
             self.render_text_input('contact_name', self.contact_name),
 
             tags.script(r"$(document).ready(function () { $('#contact_id').formSelectPreset({textTarget: $('#contact_name')}); });"),
@@ -368,18 +382,15 @@
         """
         
         return (
-            self.render_text_input('event_start', (self.event_start.strftime(self.DATETIME_FORMAT) if event_start else None)),
+            self.render_datetime_input('event_start', self.event_start),
             " - ",
-            self.render_text_input('event_end', (self.event_end.strftime(self.DATETIME_FORMAT) if event_end else None)),
+            self.render_datetime_input('event_end', self.event_end),
 
             tags.script(r"""
 $(document).ready(function () { 
     var event_start = $('#event_start');
     var event_end = $('#event_end');
 
-    event_start.datetimepicker();
-    event_end.datetimepicker(); 
-    
 /* Buggy shit doesn't work
 
     {
@@ -474,23 +485,30 @@
 
 
 class OrdersView (PageHandler) :
-    def render (self) :
+    def render_content (self) :
         return tags.h1("Orders list")
 
 class OrderView (PageHandler) :
-    def render (self, id) :
+    def render_content (self, id) :
         return tags.h1("Order info for #%d" % (id, ))
 
 class NewOrderView (PageHandler) :
     """
-        
+            
     """
 
-    def render (self) :
+    def render_content (self) :
+
+        form = OrderForm(self.app)
+        form.defaults()
+
+        return form.render(action=self.url_for(NewOrderView))
+
+        # XXX: under construction..
+
         if self.POST :
             print self.POST
 
-            # 
             
             # if we've gotten this far, then we can create it!
             sql = db.insert(db.orders).values(
@@ -509,7 +527,5 @@
             # ok, we don't need the /new URL anymore, we can just show the order page
             return self.redirect_for(OrderView, id=order_id)
 
-        # render form
-        return self.render_form()