some vodoo for generating correct URLs
authorTero Marttila <terom@fixme.fi>
Fri, 06 Feb 2009 23:55:23 +0200
changeset 10 d83b10c210e3
parent 9 2a47b00f60b0
child 11 fa216534ae45
some vodoo for generating correct URLs
lib/handler.py
lib/http.py
lib/page.py
pages/debug.tmpl
pages/error404.py
pages/list
pages/projects/index.html
pages/projects/index.py
templates/layout.tmpl
--- a/lib/handler.py	Fri Feb 06 23:21:24 2009 +0200
+++ b/lib/handler.py	Fri Feb 06 23:55:23 2009 +0200
@@ -15,9 +15,13 @@
     # get the page handler
     p = page.lookup(page_name)
 
+    # bind to request
+    p.bind_request(request)
+
     # render the template
     response_data = template.render("layout",
         site_root_url   = request.get_script_dir(),
+        site_page_url   = request.get_page_prefix(),
         page            = p,
         menu            = menu.Menu(p),
     )
--- a/lib/http.py	Fri Feb 06 23:21:24 2009 +0200
+++ b/lib/http.py	Fri Feb 06 23:55:23 2009 +0200
@@ -41,6 +41,34 @@
 
         return os.path.dirname(self.env['SCRIPT_NAME'])
     
+    def get_page_prefix (self) :
+        """
+            Returns the URL path root for page URLs, based on REQUEST_URI with PATH_INFO removed
+
+            /                   -> 
+            /foo.cgi            -> /foo.cgi
+            /foo.cgi/index      -> /foo.cgi
+            /foo.cgi/quux/bar   -> /foo.cgi
+            /quux/foo.cgi/bar   -> /quux/foo.cgi
+            /bar                -> 
+        """
+        
+        # XXX: request uri path without the query string
+        request_path = self.env.get('REQUEST_URI', '').split('?', 1)[0].rstrip('/')
+
+        # path info
+        page_name = self.get_page_name()
+
+        # special-case for empty page_name
+        if not page_name :
+            return request_path
+        
+        # sanity-check
+        assert request_path.endswith(page_name)
+        
+        # trim
+        return request_path[:-len(page_name)].rstrip('/')
+
     def get_page_name (self) :
         """
             Returns the requested page path with no leading slash, i.e.
--- a/lib/page.py	Fri Feb 06 23:21:24 2009 +0200
+++ b/lib/page.py	Fri Feb 06 23:55:23 2009 +0200
@@ -65,6 +65,10 @@
             Add item to pages list
         """
 
+        # remove index from URL
+        if url.endswith('/index') or url == 'index' :
+            url = url[:-len('/index')]
+
         self.pages.append((url, title))
     
     def get_title (self, page) :
@@ -120,6 +124,9 @@
         self.basename = basename
         self.url_tail = url_tail
 
+        # unbound
+        self.request = None
+
         # sub-init
         self._init()
 
@@ -130,6 +137,13 @@
         
         pass
 
+    def bind_request (self, request) :
+        """
+            Bind this page-render to the given request
+        """
+
+        self.request = request
+
     @property
     def title (self) :
         """
@@ -179,7 +193,9 @@
             Loads the .tmpl file, and renders it
         """
 
-        return template.render_file(self.path)
+        return template.render_file(self.path,
+            request     = self.request,
+        )
 
 # list of page handlers, by type
 TYPE_HANDLERS = [
@@ -215,17 +231,19 @@
     segments = name.split('/')
 
     # iterate through the parts of the page segments
-    while segments :
+    while True :
+        segment = None
+
         # pop segment
-        segment = segments.pop(0)
+        if segments :
+            segment = segments.pop(0)
 
-        # add to page url
-        url_segments.append(segment)
+            url_segments.append(segment)
 
         # translate empty -> index
         if not segment :
             segment = 'index'
-        
+
         # look for it in the dir
         for filename in os.listdir(path) :
             # build full file path
@@ -254,6 +272,10 @@
                 # inspect next file in dir
                 continue
 
+        else :
+            # did not find any dir or file, break out of while loop
+            break
+
     # did not find the filename we were looking for in os.listdir
     raise PageError("Page not found: %s" % name, status='404 Not Found')
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pages/debug.tmpl	Fri Feb 06 23:55:23 2009 +0200
@@ -0,0 +1,8 @@
+
+<dl>
+    <lh>List of request env variables</lh>
+
+% for key, val in request.env.iteritems() :
+    <dt>${key}</dt> <dd>${val}</dd>
+% endfor
+</dl>
--- a/pages/error404.py	Fri Feb 06 23:21:24 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-
-import templates
-import page
-import index
-
-class Error404 (page.Page) :
-    title = "Error 404 - Not Found"
-
-    parent = index.Page
-
-    def get_response_code (self) :
-        return 404
-
-    def render_template (self) :
-        return self._build_template(templates.error_404)
-
--- a/pages/list	Fri Feb 06 23:21:24 2009 +0200
+++ b/pages/list	Fri Feb 06 23:55:23 2009 +0200
@@ -1,5 +1,6 @@
 
 index       : Index
 foo         : Foo
+projects    : Projects list
 about       : About page
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pages/projects/index.html	Fri Feb 06 23:55:23 2009 +0200
@@ -0,0 +1,1 @@
+Projects list
--- a/pages/projects/index.py	Fri Feb 06 23:21:24 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-import page
-
-class Page (page.Page) :
-    pass
-
--- a/templates/layout.tmpl	Fri Feb 06 23:21:24 2009 +0200
+++ b/templates/layout.tmpl	Fri Feb 06 23:55:23 2009 +0200
@@ -12,7 +12,7 @@
  
             <ul id="nav">
             % for (url, title) in menu.siblings :
-                <li><a href="${url}"${' class="selected-page"' if url == page.url else ''}>${title}</a></li>
+                <li><a href="${site_page_url}/${url}"${' class="selected-page"' if url == page.url else ''}>${title}</a></li>
             % endfor
             </ul>