pages: tree parents, hierarchy; tree/page titles
authorTero Marttila <terom@paivola.fi>
Sun, 14 Sep 2014 02:52:40 +0300
changeset 205 f1adf52f485a
parent 204 99f9e50030ae
child 206 440e6769976c
pages: tree parents, hierarchy; tree/page titles
qmsk_www_pages/pages.py
qmsk_www_pages/templates/pages/page.html
qmsk_www_pages/views.py
--- a/qmsk_www_pages/pages.py	Sun Sep 14 02:28:42 2014 +0300
+++ b/qmsk_www_pages/pages.py	Sun Sep 14 02:52:40 2014 +0300
@@ -5,6 +5,9 @@
 import logging; log = logging.getLogger('qmsk_www_pages.pages')
 import os, os.path
 
+class NotFound (Exception):
+    pass
+
 class Site (object):
     @classmethod
     def lookup (cls):
@@ -22,33 +25,67 @@
 
     @classmethod
     def lookup (cls, site, parts):
-        path = site.root
+        """
+            Returns Tree
 
-        for part in parts:
-            if part.startswith('.'):
+            Raises NotFound
+        """
+
+        parents = ( )
+        tree = cls(site.root, None, parents, site,
+                title       = site.name,
+        )
+
+        for name in parts:
+            if name.startswith('.'):
                 # evil
-                return None
+                raise NotFound()
             
-            if not part:
+            if not name:
                 continue
         
-            path = os.path.join(path, part)
+            path = os.path.join(tree.path, name)
 
             if not os.path.exists(path):
-                return None
+                raise NotFound()
             
             if not os.path.isdir(path):
-                return None
-        
-        return cls(path, parts, site)
+                raise NotFound()
 
-    def __init__ (self, path, parts, site):
+            parents += (tree, )
+            tree = cls(path, name, parents, site)
+
+        return tree
+
+    def __init__ (self, path, name, parents, site,
+            title   = None,
+    ):
+        """
+            path:       filesystem path
+            name:       subtree name, or None for root
+            parents:    (Tree)
+            site:       Site
+        """
+
         self.path = path
-        self.parts = parts
+        self.name = name
+        self.parents = parents
         self.site = site
 
+        self.title = title or name
+
+    def hierarchy (self):
+        """
+            Yield Tree.
+        """
+
+        for tree in self.parents:
+            yield tree
+
+        yield self
+
     def url (self, tree=None, page=None):
-        path = '/'.join(self.parts)
+        path = '/'.join(tree.name for tree in self.hierarchy() if tree.name is not None)
 
         if path:
             path += '/'
@@ -61,16 +98,6 @@
 
         return path
 
-    def breadcrumb (self):
-        path = []
-
-        yield '', self.site.name
-
-        for part in self.parts:
-            path.append(part)
-
-            yield '/'.join(path) + '/', part
-
     def scan (self):
         """
             Scan for files in tree.
@@ -119,7 +146,7 @@
         """
             Scans through tree looking for a matching page.
             
-            Returns Page.
+            Returns Page or None.
         """
         
         if not name:
@@ -144,6 +171,7 @@
                 path    = path,
                 name    = name,
                 tree    = self,
+                parents = self.parents + (self, ),
             )
 
 class Page (object):
@@ -152,9 +180,9 @@
     @classmethod
     def lookup (cls, site, page):
         """
-            Lookup a Page from disk.
-
-            Returns None if there is no such page.
+            Returns Page.
+            
+            Raises NotFound
         """
         
         log.info("page=%r", page)
@@ -174,22 +202,22 @@
         # scan dir
         tree = Tree.lookup(site, tree_parts)
 
-        if not tree:
-            return None
-
         # scan page
         page = tree.page(page_name)
 
         if not page:
-            return None
+            raise NotFound()
 
         return page
 
-    def __init__ (self, path, name, tree, encoding=ENCODING):
+    def __init__ (self, path, name, tree, parents=(), encoding=ENCODING, title=None):
         self.path = path
         self.name = name
         self.tree = tree
+        self.parents = parents
+
         self.encoding = encoding
+        self.title = title or name
 
     def url (self):
         return self.tree.url(page=self.name)
@@ -201,11 +229,11 @@
         return os.stat(self.path)
 
     def breadcrumb (self):
-        for path, name in self.tree.breadcrumb():
-            yield path, name
+        for tree in self.tree.hierarchy():
+            yield tree.url(), tree.title
         
         if self.name != self.tree.INDEX:
-            yield self.url(), self.name
+            yield self.url(), self.title
 
     def modified (self):
         return datetime.datetime.utcfromtimestamp(self.stat().st_mtime)
--- a/qmsk_www_pages/templates/pages/page.html	Sun Sep 14 02:28:42 2014 +0300
+++ b/qmsk_www_pages/templates/pages/page.html	Sun Sep 14 02:52:40 2014 +0300
@@ -1,6 +1,6 @@
 {% extends "site.html" %}
 
-{% block title %}{{ site_name }} :: {{ page_name }}{% endblock %}
+{% block title %}{{ site_name }} :: {{ page_title }}{% endblock %}
 
 {% block content %}
     <div class="container">
@@ -11,21 +11,21 @@
         </div>
         <div id="breadcrumb">
             <ol class="breadcrumb">
-                {% for page, name in page_breadcrumb %}
-                <li><a href="{% url 'page' page %}">{{ name }}</a></li>
+                {% for page, title in page_breadcrumb %}
+                <li><a href="{% url 'page' page %}">{{ title }}</a></li>
                 {% endfor %}
             </ol>
         </div>
         <div class="row">
             <div class="col-sm-2" id="nav">
-                {% for page, name in tree_breadcrumb %}
+                {% for tree in tree_hierarchy %}
                 <ul class="nav">
-                    <li><a href="{% url 'page' page %}">{{ name }}</a></li>
+                    <li><a href="{% url 'page' tree.url %}">{{ tree.title }}</a></li>
                 </ul>
                 <hr />
                 {% endfor %}
                 <ul class="nav">
-                    {% for page, name, type in page_list %}
+                    {% for page, name, type in tree_list %}
                     <li class="page-tree-item{% if name == page_name %} page-tree-active{% endif %}{% if type %} page-tree-{{type}}{% else %} page-tree-tree{% endif %}">
                         <a href="{% url 'page' page %}">{{ name }}</a>
                     </li>
@@ -33,7 +33,7 @@
                 </ul>
             </div>
             <div class="col-sm-8" id="content">
-                <!-- <h1>{{ page_name }}</h1> -->
+                <!-- <h1>{{ page_title }}</h1> -->
 
                 {{ page_html|safe }}
             </div>
--- a/qmsk_www_pages/views.py	Sun Sep 14 02:28:42 2014 +0300
+++ b/qmsk_www_pages/views.py	Sun Sep 14 02:52:40 2014 +0300
@@ -12,10 +12,11 @@
 
     return render(request, 'pages/page.html', dict(
             site_name       = page.tree.site.name,
-            tree_breadcrumb = page.tree.breadcrumb(),
+            tree_hierarchy  = list(page.tree.hierarchy()),
+            tree_list       = list(page.tree.list()),
             page_name       = page.name,
+            page_title      = page.title,
             page_breadcrumb = page.breadcrumb(),
-            page_list       = page.tree.list(),
             page_html       = page.render(request),
             page_modified   = page.modified(),
     ))