start breaking everything
authorTero Marttila <terom@fixme.fi>
Fri, 06 Feb 2009 20:49:29 +0200
changeset 6 5565d94da522
parent 5 9ed4c7d2bdd2
child 7 d6a8258bd90e
start breaking everything
index.cgi
lib/Makefile
lib/__init__.py
lib/index.py
lib/loaders.py
lib/page.py
lib/request.py
pages/__init__.py
pages/about.html
pages/error404.py
pages/index.py
pages/projects/index.py
site/Makefile
site/__init__.py
site/index.py
site/loaders.py
site/page.py
site/pages/__init__.py
site/pages/about.html
site/pages/error404.py
site/pages/index.py
site/pages/projects/index.py
site/request.py
site/templates/__init__.py
site/templates/error_404.tmpl
site/templates/layout.tmpl
site/templates/main.tmpl
site/templates/projects.tmpl
static/style.css
stuff/.placeholder
style.css
templates/__init__.py
templates/error_404.tmpl
templates/layout.tmpl
templates/main.tmpl
templates/projects.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index.cgi	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,3 @@
+#!/usr/bin/python2.5
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/Makefile	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,6 @@
+
+all: $(patsubst %.tmpl,%.py,$(wildcard templates/*.tmpl))
+
+templates/%.py: templates/%.tmpl
+	@cheetah compile --nobackup $<
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/index.py	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,44 @@
+#!/usr/bin/env python2.5
+
+DEBUG = True
+
+# imports
+if DEBUG :
+    import cgitb; cgitb.enable()
+
+# system modules
+import cgi, os
+
+# my modules/packages
+import request
+import loaders
+
+def dump_environ () :
+    print "<!--"
+
+    for k, v in os.environ.iteritems() :
+        print "%25s: %s" % (k, v)
+    
+    print "-->"
+
+# main
+def main (environ) :
+    # load our req
+    req = request.Request(environ, default_page='main')
+
+    # get the page handler
+    page = loaders.load_page(req)
+    
+    # render
+    print "Status: %d\r\n" % page.get_response_code(),
+    print "Content-Type: text/html\r\n",
+    print "\r\n",
+    print "%s\r\n" % page.render_template()
+    
+    # debug output
+    if DEBUG :
+        dump_environ()
+
+if __name__ == '__main__' :
+    main(os.environ)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/loaders.py	Fri Feb 06 20:49:29 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/lib/page.py	Fri Feb 06 20:49:29 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
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/request.py	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,73 @@
+
+import os.path
+
+def get_site_url (script_name) :
+    """
+        Get the URL that points to the site root (i.e. where style.css is) using the given value of SCRIPT_NAME
+
+        /foo/bar/quux.py                -> /foo
+        /~terom/qmsk.net/site/index.py  -> /~terom/qmsk.net
+        /                               -> ""
+        None                            -> ""
+    """
+    
+    if script_name :
+        return os.path.dirname(os.path.dirname(script_name)).rstrip("/")
+    else :
+        return ""
+
+def get_page_path (path_info, default) :
+    """
+        Get the path of the page that was requested, or the given default is empty/invalid.
+        The path will never begin with an /.
+
+        /quux       -> quux
+        /           -> <default>
+        None        -> <default>
+    """
+    
+    if path_info :
+        # remove prefixed slashes
+        path_info = path_info.lstrip('/')
+
+    if path_info :
+        return path_info
+    else :
+        return default
+
+
+class Request (object) :
+    # The name of the site itself, this can be used to reference e.g. style.css
+    site_url = None
+
+    # The page root url, for links to pages
+    page_root = None
+
+    # The full path to the requested page
+    page_path = None
+    
+    def __init__ (self, environ, default_page='main') :
+        self.site_url = get_site_url(environ.get("SCRIPT_NAME"))
+        self.page_root = environ.get("SCRIPT_NAME")
+        self.page_path = get_page_path(environ.get("PATH_INFO"), default_page)
+    
+    def page_name_parts (self) :
+        """
+            Returns a list of page name components
+        """
+
+        return self.page_path.split('/')
+
+    def page_name_prefixes (self) :
+        """
+            Iterate over the components of the page name, yielding (prefix, suffix) pairs
+        """
+        
+        prefix = self.page_name_parts()
+        suffix = []
+
+        while prefix :
+            yield ('/'.join(prefix), '/'.join(suffix))
+
+            suffix.insert(0, prefix.pop(-1))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pages/about.html	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,4 @@
+<h1>Simple About Page</h1>
+
+<p>This is a simple about page, implemented using plain HTML</p>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pages/error404.py	Fri Feb 06 20:49:29 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/pages/index.py	Fri Feb 06 20:49:29 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/pages/projects/index.py	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,6 @@
+
+import page
+
+class Page (page.Page) :
+    pass
+
--- a/site/Makefile	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-all: $(patsubst %.tmpl,%.py,$(wildcard templates/*.tmpl))
-
-templates/%.py: templates/%.tmpl
-	@cheetah compile --nobackup $<
-
--- a/site/index.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#!/usr/bin/env python2.5
-
-DEBUG = True
-
-# imports
-if DEBUG :
-    import cgitb; cgitb.enable()
-
-# system modules
-import cgi, os
-
-# my modules/packages
-import request
-import loaders
-
-def dump_environ () :
-    print "<!--"
-
-    for k, v in os.environ.iteritems() :
-        print "%25s: %s" % (k, v)
-    
-    print "-->"
-
-# main
-def main (environ) :
-    # load our req
-    req = request.Request(environ, default_page='main')
-
-    # get the page handler
-    page = loaders.load_page(req)
-    
-    # render
-    print "Status: %d\r\n" % page.get_response_code(),
-    print "Content-Type: text/html\r\n",
-    print "\r\n",
-    print "%s\r\n" % page.render_template()
-    
-    # debug output
-    if DEBUG :
-        dump_environ()
-
-if __name__ == '__main__' :
-    main(os.environ)
-
--- a/site/loaders.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-
-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)
-
--- a/site/page.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-
-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/about.html	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<h1>Simple About Page</h1>
-
-<p>This is a simple about page, implemented using plain HTML</p>
-
--- a/site/pages/error404.py	Fri Feb 06 20:46:43 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/site/pages/index.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-
-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)
-
--- a/site/pages/projects/index.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-import page
-
-class Page (page.Page) :
-    pass
-
--- a/site/request.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-
-import os.path
-
-def get_site_url (script_name) :
-    """
-        Get the URL that points to the site root (i.e. where style.css is) using the given value of SCRIPT_NAME
-
-        /foo/bar/quux.py                -> /foo
-        /~terom/qmsk.net/site/index.py  -> /~terom/qmsk.net
-        /                               -> ""
-        None                            -> ""
-    """
-    
-    if script_name :
-        return os.path.dirname(os.path.dirname(script_name)).rstrip("/")
-    else :
-        return ""
-
-def get_page_path (path_info, default) :
-    """
-        Get the path of the page that was requested, or the given default is empty/invalid.
-        The path will never begin with an /.
-
-        /quux       -> quux
-        /           -> <default>
-        None        -> <default>
-    """
-    
-    if path_info :
-        # remove prefixed slashes
-        path_info = path_info.lstrip('/')
-
-    if path_info :
-        return path_info
-    else :
-        return default
-
-
-class Request (object) :
-    # The name of the site itself, this can be used to reference e.g. style.css
-    site_url = None
-
-    # The page root url, for links to pages
-    page_root = None
-
-    # The full path to the requested page
-    page_path = None
-    
-    def __init__ (self, environ, default_page='main') :
-        self.site_url = get_site_url(environ.get("SCRIPT_NAME"))
-        self.page_root = environ.get("SCRIPT_NAME")
-        self.page_path = get_page_path(environ.get("PATH_INFO"), default_page)
-    
-    def page_name_parts (self) :
-        """
-            Returns a list of page name components
-        """
-
-        return self.page_path.split('/')
-
-    def page_name_prefixes (self) :
-        """
-            Iterate over the components of the page name, yielding (prefix, suffix) pairs
-        """
-        
-        prefix = self.page_name_parts()
-        suffix = []
-
-        while prefix :
-            yield ('/'.join(prefix), '/'.join(suffix))
-
-            suffix.insert(0, prefix.pop(-1))
-
--- a/site/templates/__init__.py	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-
-# system imports
-from Cheetah.Template import Template as _CheetahTemplate
-
-# base template
-class _BaseTemplate (_CheetahTemplate) :
-    def __init__ (self, req) :
-        """
-            Blah
-        """
-
-        # XXX: not done
-        pass
-
-
-# import templates
-from layout import layout
-from main import main
-from error_404 import error_404
-
--- a/site/templates/error_404.tmpl	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#extends layout
-#def page_content
-<h1>Oops! Not Found</h1>
-
-<p>The page you requested does not seem to exist. Perhaps you can find what you're looking for in the menu at the left?</p>
-
-<pre>
-    Requested Path: $page_path
-</pre>
-#end def
--- a/site/templates/layout.tmpl	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-#def page_title
-qmsk.net
-#end def
-#def page_content
-<h1>Content Goes Here</h1>
-
-Content goes here.
-#end def
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-    <head>
-        <title>qmsk.net :: $page_title</title>
-        <link rel="Stylesheet" type="text/css" href="$site_url/style.css" />
-    </head>
-    <body>
-            <div id="header">
-                QMSK.NET
-            </div>
- 
-            <ul id="nav">
-                #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>
-
-            <div id="content">
-                $page_content
-            </div>
-    </body>
-</html>
-
--- a/site/templates/main.tmpl	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-#extends layout
-#def page_content
-<h1>Main Page</h1>
-
-<p>This is the main page...</p>
-#end def
--- a/site/templates/projects.tmpl	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-#extends layout
-#def page_content
-<h1>Projects</h1>
-
-<p>A variety of projects...</p>
-#end def
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static/style.css	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,92 @@
+
+/*
+ * Three main areas:
+ *  header
+ *  nav
+ *  content
+ *
+ * Border layout:
+ *      Header (bottom)
+ *      Content (left)
+ */
+
+/*
+ * Global styles
+ */
+body {
+    padding: 0px;
+    margin: 0px;
+
+    background-color: #ffffff;
+    color: #000000;
+}
+
+a {
+    color: black;
+    text-decoration: none;
+    font-weight: bold;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+/*
+ * Top header
+ */
+div#header {
+    padding: 30px;
+    
+    font-size: 48pt;
+    font-weight: bold;
+
+    border-bottom: 1px dashed #a5a5a5;
+}
+
+/*
+ * Main navigation menu
+ */
+ul#nav {
+    float: left;
+    margin: 0px;
+    padding: 0px;
+
+    list-style: none;
+
+    width: 180px;
+
+    padding-top: 25px;
+}
+
+ul#nav li a {
+    display: block;
+    
+    padding: 10px;
+    padding-left: 20px;
+}
+
+ul#nav li a:hover {
+    background-color: #d0d0d0;
+    text-decoration: none;
+}
+
+ul#nav li a#selected-page {
+    border-left: 5px solid black;
+    padding-left: 15px;
+}
+
+/*
+ * Content
+ */
+div#content {
+    margin-left: 180px;
+
+    padding: 25px;
+
+    border-left: 1px dashed #a5a5a5;
+}
+
+div#content p {
+    text-indent: 2em;
+
+}
--- a/style.css	Fri Feb 06 20:46:43 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-
-/*
- * Three main areas:
- *  header
- *  nav
- *  content
- *
- * Border layout:
- *      Header (bottom)
- *      Content (left)
- */
-
-/*
- * Global styles
- */
-body {
-    padding: 0px;
-    margin: 0px;
-
-    background-color: #ffffff;
-    color: #000000;
-}
-
-a {
-    color: black;
-    text-decoration: none;
-    font-weight: bold;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-/*
- * Top header
- */
-div#header {
-    padding: 30px;
-    
-    font-size: 48pt;
-    font-weight: bold;
-
-    border-bottom: 1px dashed #a5a5a5;
-}
-
-/*
- * Main navigation menu
- */
-ul#nav {
-    float: left;
-    margin: 0px;
-    padding: 0px;
-
-    list-style: none;
-
-    width: 180px;
-
-    padding-top: 25px;
-}
-
-ul#nav li a {
-    display: block;
-    
-    padding: 10px;
-    padding-left: 20px;
-}
-
-ul#nav li a:hover {
-    background-color: #d0d0d0;
-    text-decoration: none;
-}
-
-ul#nav li a#selected-page {
-    border-left: 5px solid black;
-    padding-left: 15px;
-}
-
-/*
- * Content
- */
-div#content {
-    margin-left: 180px;
-
-    padding: 25px;
-
-    border-left: 1px dashed #a5a5a5;
-}
-
-div#content p {
-    text-indent: 2em;
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/__init__.py	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,20 @@
+
+# system imports
+from Cheetah.Template import Template as _CheetahTemplate
+
+# base template
+class _BaseTemplate (_CheetahTemplate) :
+    def __init__ (self, req) :
+        """
+            Blah
+        """
+
+        # XXX: not done
+        pass
+
+
+# import templates
+from layout import layout
+from main import main
+from error_404 import error_404
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/error_404.tmpl	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,10 @@
+#extends layout
+#def page_content
+<h1>Oops! Not Found</h1>
+
+<p>The page you requested does not seem to exist. Perhaps you can find what you're looking for in the menu at the left?</p>
+
+<pre>
+    Requested Path: $page_path
+</pre>
+#end def
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/layout.tmpl	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+#def page_title
+qmsk.net
+#end def
+#def page_content
+<h1>Content Goes Here</h1>
+
+Content goes here.
+#end def
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <head>
+        <title>qmsk.net :: $page_title</title>
+        <link rel="Stylesheet" type="text/css" href="$site_url/style.css" />
+    </head>
+    <body>
+            <div id="header">
+                QMSK.NET
+            </div>
+ 
+            <ul id="nav">
+                #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>
+
+            <div id="content">
+                $page_content
+            </div>
+    </body>
+</html>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/main.tmpl	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,6 @@
+#extends layout
+#def page_content
+<h1>Main Page</h1>
+
+<p>This is the main page...</p>
+#end def
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/projects.tmpl	Fri Feb 06 20:49:29 2009 +0200
@@ -0,0 +1,6 @@
+#extends layout
+#def page_content
+<h1>Projects</h1>
+
+<p>A variety of projects...</p>
+#end def