older work
authorTero Marttila <terom@fixme.fi>
Fri, 06 Feb 2009 20:46:43 +0200
changeset 5 9ed4c7d2bdd2
parent 4 622592427cec
child 6 5565d94da522
older work
site/index.py
site/loaders.py
site/page.py
site/pages/__init__.py
site/pages/error404.py
site/pages/index.py
site/pages/projects/index.py
site/templates/layout.tmpl
site/templates/projects.tmpl
--- a/site/index.py	Sat Dec 13 21:00:40 2008 +0200
+++ b/site/index.py	Fri Feb 06 20:46:43 2009 +0200
@@ -11,7 +11,7 @@
 
 # my modules/packages
 import request
-import pages
+import loaders
 
 def dump_environ () :
     print "<!--"
@@ -27,7 +27,7 @@
     req = request.Request(environ, default_page='main')
 
     # get the page handler
-    page = pages.find(req)
+    page = loaders.load_page(req)
     
     # render
     print "Status: %d\r\n" % page.get_response_code(),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/loaders.py	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,160 @@
+
+from __future__ import with_statement
+
+# XXX: for _HTMLPage
+import page
+import templates
+
+from pages import error404
+
+import os.path
+import imp
+
+# the page dir
+PAGE_DIR_PATH = "pages/"
+
+def build_page_path (*bits) :
+    # XXX: fix directory traversal...
+    
+    return os.path.join(PAGE_DIR_PATH, *bits)
+
+class PageLoader (object) :
+    """
+        Load Page objects from files under pages/
+    """
+    
+    # file extension, e.g. '.html' or '.py'
+    suffix = None
+
+    def __init__ (self, suffix) :
+        self.suffix = suffix
+        
+    def _build_path (self, page_path) :
+        """
+            Builds a path from base_path + page_path + suffix. Returns None if the path does not exist
+        """
+        
+        path = build_page_path(page_path) + self.suffix
+
+        if os.path.exists(path) :
+            return path
+
+        else :
+            return None
+
+    def load (self, page_path) :
+        """
+            Attempts to load the page at the given path, returns the class on success, None on failure
+        """
+        
+        abstract
+
+class _HTMLPage (page.Page) :
+    # the path to the .html file
+    file_path = None
+    
+    # parent page
+    # parent = None
+
+    def __init__ (self, *args) :
+        super(_HTMLPage, self).__init__(*args)
+
+        # open the .html and read in the contents
+        with open(self.file_path, "r") as fh :
+            self.file_data = fh.read()
+
+    def render_template (self) :
+        tpl = self._build_template(templates.layout)
+        
+        tpl.page_content = self.file_data
+        
+        return tpl
+
+class HTMLLoader (PageLoader) :
+    """
+        Static .html files that are inserted into the layout template as-is
+
+        Sub-pages are not supported...
+    """
+
+    def __init__ (self) :
+        super(HTMLLoader, self).__init__(".html")
+
+    def get_title (self, page_path) :
+        head, tail = os.path.split(page_path)
+
+        return tail.title() if tail else "Index"
+
+    def load (self, _page_path) :
+        _file_path = self._build_path(_page_path)
+        
+        # ignore if it doesn't exist
+        if not _file_path :
+            return
+        
+        # get page title
+        _title = self.get_title(_page_path)
+
+        # create a new class and return it
+        class _html_page (_HTMLPage) :
+            file_path = _file_path
+            title = _title
+            name = _title
+            path = _page_path
+            
+        # return it
+        return _html_page
+
+class PythonLoader (PageLoader) :
+    """
+        Dynamic .py files that define a Page class
+    """
+
+    def __init__ (self) :
+        super(PythonLoader, self).__init__(".py")
+    
+    def load (self, page_path) :
+        path = self._build_path(page_path)
+
+        # ignore if not exists
+        if not path :
+            return
+
+        # load the module dynamically
+        module = imp.load_source("__dyn_%d" % id(path), path)
+
+        # return the Page object
+        return module.Page
+
+# our defined loaders
+loaders = [
+    HTMLLoader(),
+    PythonLoader(),
+]
+
+def load_page (req) :
+    """
+        Returns an instance of a Page object corresponding to the given req
+    """
+
+    # page path is given in req
+    page_path = req.page_path
+
+    # if it's a dir, then add 'index'
+    if os.path.isdir(build_page_path(page_path)) :
+        page_path = os.path.join(page_path, "index")
+
+    # try each loader in turn
+    for loader in loaders :
+        page = loader.load(req.page_path)
+        
+        # found?
+        if page :
+            break
+
+    # 404 error...
+    if not page :
+        page = error404.Error404
+        
+    return page(req, req.page_path)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/page.py	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,59 @@
+
+class Page (object) :
+    """
+        A page is kind of like a controller, I guess
+    """
+
+    # the page title, used in the HTML <title>
+    title = None
+
+    # the page name, used in the menu
+    name = None
+
+    # the page path, used in the URL
+    path = None
+
+    # parent page, can be self
+    parent = None
+
+    # menu of sub-pages, may be empty
+    menu = None
+
+    def __init__ (self, req, path_suffix) :
+        self.req = req
+        self.path_suffix = path_suffix
+
+        # default parent to root
+        if not self.parent :
+            from pages import index as index_page
+
+            self.parent = index_page.Page
+    
+    def _build_template (self, template_class) :
+        tpl = template_class(searchList=[self.req])
+        
+        tpl.page_title = self.title
+        tpl.page_name = self.name
+        tpl.page_path = self.path
+
+        tpl.page_menu = self.menu
+        tpl.page = self
+        
+        return tpl
+    
+    def get_response_code (self) :
+        """
+            Returns the HTTP response code to be used
+        """
+
+        return 200
+
+    def render_template (self) :
+        """
+            Returns an instance of Cheetah.Template, prepopulated with whatever variables it needs, ready to be rendered
+        """
+
+        abstract
+
+
+
--- a/site/pages/__init__.py	Sat Dec 13 21:00:40 2008 +0200
+++ b/site/pages/__init__.py	Fri Feb 06 20:46:43 2009 +0200
@@ -1,131 +0,0 @@
-
-import templates as _templates
-
-class _Page (object) :
-    """
-        A page is kind of like a controller, I guess
-    """
-
-    # the page title, used in the HTML <title>
-    title = None
-
-    # the page name, used in the menu
-    name = None
-
-    # the page path, used in the URL
-    path = None
-
-    def __init__ (self, req, path_suffix) :
-        self.req = req
-        self.path_suffix = path_suffix
-    
-    def _build_template (self, template_class) :
-        tpl = template_class(searchList=[self.req])
-        
-        tpl.page_title = self.title
-        tpl.page_name = self.name
-        tpl.page_path = self.path
-
-        tpl.page_menu = root_menu
-        tpl.page = self
-        tpl.page_children = self.get_children()
-        
-        return tpl
-
-    def get_children (self) :
-        """
-            Returns a list of page objects that are children of this one. May return None if there are none
-        """
-
-        return None
-    
-    def get_response_code (self) :
-        """
-            Returns the HTTP response code to be used
-        """
-
-        return 200
-
-    def render_template (self) :
-        """
-            Returns an instance of Cheetah.Template, prepopulated with whatever variables it needs, ready to be rendered
-        """
-
-        abstract
-
-class StaticHTML (_Page) :
-    # the path to the .html file
-    file_path = None
-
-    def __init__ (self, *args) :
-        super(StaticHTML, self).__init__(*args)
-
-        # open the .html and read in the contents
-        fh = open(self.file_path, "r")
-
-        self.file_data = fh.read()
-
-        fh.close()
-
-    def render_template (self) :
-        tpl = self._build_template(_templates.layout)
-        
-        tpl.page_content = self.file_data
-        
-        return tpl
-
-def html_page (_file_path, _title, _name, _path) :
-    class _anon_html_page (StaticHTML) :
-        file_path = _file_path
-        title = _title
-        name = _name
-        path = _path
-
-    return _anon_html_page
-
-class Main (_Page) :
-    """
-        Main page with simple stuff
-    """
-    
-    title = "Main Page"
-    name = "Main"
-    path = ""
-
-    def render_template (self) :
-        return self._build_template(_templates.main)
-
-
-class Error404 (_Page) :
-    title = "Error 404 - Not Found"
-
-    def get_response_code (self) :
-        return 404
-
-    def render_template (self) :
-        return self._build_template(_templates.error_404)
-
-# load HTML pages
-About = html_page("pages/about.html", "About", "About", "about")
-
-pages = {
-    'main': Main,
-    'about': About,
-}
-
-root_menu = [
-    Main,
-    About
-]
-
-def find (req) :
-    """
-        This finds the page to use for the given req and reuturns an instance of it
-    """
-
-    for prefix, suffix in req.page_name_prefixes() :
-        if prefix in pages :
-            return pages[prefix](req, suffix)
-    
-    return Error404(req, req.page_path)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/pages/error404.py	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,16 @@
+
+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)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/pages/index.py	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,21 @@
+
+import page
+
+class Page (page.Page) :
+    """
+        Main page with simple stuff
+    """
+    
+    title = "Main Page"
+    name = "Main"
+    path = ""
+    
+    parent = None
+    menu = [
+        "",
+        "main"
+    ]
+
+    def render_template (self) :
+        return self._build_template(_templates.main)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/pages/projects/index.py	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,6 @@
+
+import page
+
+class Page (page.Page) :
+    pass
+
--- a/site/templates/layout.tmpl	Sat Dec 13 21:00:40 2008 +0200
+++ b/site/templates/layout.tmpl	Fri Feb 06 20:46:43 2009 +0200
@@ -20,8 +20,8 @@
             </div>
  
             <ul id="nav">
-                #for $menu_page in $page_menu
-                <li><a href="$page_root/$menu_page.path"#if isinstance($page, $menu_page) then ' id="selected-page"' else '' #>$menu_page.name</a></li>
+                #for $menu_page_path in $page.parent.menu
+                <li><a href="$page_root/$menu_page_path"#if $page.path == $menu_page_path then ' id="selected-page"' else '' #>$menu_page_path</a></li>
                 #end for
             </ul>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/site/templates/projects.tmpl	Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,6 @@
+#extends layout
+#def page_content
+<h1>Projects</h1>
+
+<p>A variety of projects...</p>
+#end def