changeset 977:84fc72a17f7a

sources: Changes in related contents management. - Remove `getParentGroup` method, use related contents instead. - Return only a single group when asked for the parent.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 17 Oct 2017 01:11:54 -0700
parents b9374b3682f0
children 7e51d14097cb
files piecrust/data/linker.py piecrust/sources/base.py piecrust/sources/fs.py piecrust/sources/posts.py
diffstat 4 files changed, 58 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/data/linker.py	Tue Oct 17 01:09:55 2017 -0700
+++ b/piecrust/data/linker.py	Tue Oct 17 01:11:54 2017 -0700
@@ -1,7 +1,7 @@
 import logging
 from piecrust.data.paginationdata import PaginationData
 from piecrust.sources.base import (
-    REL_LOGICAL_PARENT_ITEM, REL_LOGICAl_CHILD_GROUP)
+    REL_PARENT_GROUP, REL_LOGICAL_PARENT_ITEM, REL_LOGICAl_CHILD_GROUP)
 
 
 logger = logging.getLogger(__name__)
@@ -43,53 +43,40 @@
     @property
     def ancestors(self):
         if self._ancestors is None:
-            self._ensureParentGroup()
-
             src = self._source
             app = src.app
 
-            cur_group = self._parent_group
             self._ancestors = []
+            cur_group = self._getParentGroup()
             while cur_group:
                 pi = src.getRelatedContents(cur_group,
                                             REL_LOGICAL_PARENT_ITEM)
                 if pi is not None:
                     pipage = app.getPage(src, pi)
                     self._ancestors.append(PaginationData(pipage))
-                    cur_group = src.getParentGroup(pi)
+                    cur_group = src.getRelatedContents(
+                        pi, REL_PARENT_GROUP)
                 else:
                     break
         return self._ancestors
 
     @property
     def siblings(self):
-        if self._siblings is None:
-            self._ensureParentGroup()
-
-            src = self._source
-            app = src.app
-
-            self._siblings = []
-            for i in src.getContents(self._parent_group):
-                if not i.is_group:
-                    ipage = app.getPage(src, i)
-                    self._siblings.append(PaginationData(ipage))
-        return self._siblings
+        src = self._source
+        app = src.app
+        for i in self._getAllSiblings():
+            if not i.is_group and i.spec != self._content_item.spec:
+                ipage = app.getPage(src, i)
+                yield PaginationData(ipage)
 
     @property
     def children(self):
-        if self._children is None:
-            src = self._source
-            app = src.app
-
-            self._children = []
-            child_group = src.getRelatedContents(self._content_item,
-                                                 REL_LOGICAl_CHILD_GROUP)
-            if child_group:
-                for i in src.getContents(child_group):
-                    ipage = app.getPage(src, i)
-                    self._children.append(PaginationData(ipage))
-        return self._children
+        src = self._source
+        app = src.app
+        for i in self._getAllChildren():
+            if not i.is_group:
+                ipage = app.getPage(src, i)
+                yield PaginationData(ipage)
 
     def forpath(self, path):
         # TODO: generalize this for sources that aren't file-system based.
@@ -108,11 +95,28 @@
                     yield PaginationData(ipage)
         return None
 
-    def _ensureParentGroup(self):
+    def _getAllSiblings(self):
+        if self._siblings is None:
+            self._siblings = list(self._source.getContents(
+                self._getParentGroup()))
+        return self._siblings
+
+    def _getAllChildren(self):
+        if self._children is None:
+            child_group = self._source.getRelatedContents(
+                self._content_item, REL_LOGICAl_CHILD_GROUP)
+            if child_group is not None:
+                self._children = list(
+                    self._source.getContents(child_group))
+            else:
+                self._children = []
+        return self._children
+
+    def _getParentGroup(self):
         if self._parent_group is _unloaded:
-            src = self._source
-            item = self._content_item
-            self._parent_group = src.getParentGroup(item)
+            self._parent_group = self._source.getRelatedContents(
+                self._content_item, REL_PARENT_GROUP)
+        return self._parent_group
 
     def _debugRenderAncestors(self):
         return [i.title for i in self.ancestors]
--- a/piecrust/sources/base.py	Tue Oct 17 01:09:55 2017 -0700
+++ b/piecrust/sources/base.py	Tue Oct 17 01:11:54 2017 -0700
@@ -13,8 +13,9 @@
 
 
 # Types of relationships a content source can be asked for.
-REL_LOGICAL_PARENT_ITEM = 1
-REL_LOGICAl_CHILD_GROUP = 2
+REL_PARENT_GROUP = 1
+REL_LOGICAL_PARENT_ITEM = 2
+REL_LOGICAl_CHILD_GROUP = 3
 REL_ASSETS = 10
 
 
@@ -134,10 +135,6 @@
         raise NotImplementedError(
             "'%s' doesn't implement 'getContents'." % self.__class__)
 
-    def getParentGroup(self, item):
-        raise NotImplementedError(
-            "'%s' doesn't implement 'getParentGroup'." % self.__class__)
-
     def getRelatedContents(self, item, relationship):
         raise NotImplementedError(
             "'%s' doesn't implement 'getRelatedContents'." % self.__class__)
--- a/piecrust/sources/fs.py	Tue Oct 17 01:09:55 2017 -0700
+++ b/piecrust/sources/fs.py	Tue Oct 17 01:11:54 2017 -0700
@@ -7,7 +7,7 @@
 from piecrust.routing import RouteParameter
 from piecrust.sources.base import (
     ContentItem, ContentGroup, ContentSource,
-    REL_LOGICAL_PARENT_ITEM, REL_LOGICAl_CHILD_GROUP)
+    REL_PARENT_GROUP, REL_LOGICAL_PARENT_ITEM, REL_LOGICAl_CHILD_GROUP)
 
 
 logger = logging.getLogger(__name__)
@@ -110,16 +110,6 @@
         self._finalizeContent(group, items, groups)
         return items + groups
 
-    def getParentGroup(self, item):
-        parent_dir = os.path.dirname(item.spec)
-        if len(parent_dir) >= len(self.fs_endpoint_path):
-            metadata = self._createGroupMetadata(parent_dir)
-            return ContentGroup(parent_dir, metadata)
-
-        # Don't return a group for paths that are outside of our
-        # endpoint directory.
-        return None
-
     def _filterIgnored(self, path):
         rel_path = os.path.relpath(path, self.fs_endpoint_path)
         for g in self._ignore_globs:
@@ -147,6 +137,16 @@
         return None
 
     def getRelatedContents(self, item, relationship):
+        if relationship == REL_PARENT_GROUP:
+            parent_dir = os.path.dirname(item.spec)
+            if len(parent_dir) >= len(self.fs_endpoint_path):
+                metadata = self._createGroupMetadata(parent_dir)
+                return ContentGroup(parent_dir, metadata)
+
+            # Don't return a group for paths that are outside of our
+            # endpoint directory.
+            return None
+
         if relationship == REL_LOGICAL_PARENT_ITEM:
             # If we want the logical parent item of a folder, we find a
             # page file with the same name as the folder.
@@ -167,7 +167,7 @@
             dir_path, _ = os.path.splitext(item.spec)
             if os.path.isdir(dir_path):
                 metadata = self._createGroupMetadata(dir_path)
-                return [ContentGroup(dir_path, metadata)]
+                return ContentGroup(dir_path, metadata)
             return None
 
         return None
--- a/piecrust/sources/posts.py	Tue Oct 17 01:09:55 2017 -0700
+++ b/piecrust/sources/posts.py	Tue Oct 17 01:11:54 2017 -0700
@@ -5,7 +5,7 @@
 import datetime
 from piecrust import osutil
 from piecrust.routing import RouteParameter
-from piecrust.sources.base import REL_ASSETS, ContentItem
+from piecrust.sources.base import REL_PARENT_GROUP, REL_ASSETS, ContentItem
 from piecrust.sources.fs import (
     FSContentSource, InvalidFileSystemEndpointError)
 from piecrust.sources.interfaces import (
@@ -39,13 +39,15 @@
     def _finalizeContent(self, groups):
         SimpleAssetsSubDirMixin._removeAssetGroups(self, groups)
 
-    def getParentGroup(self, item):
-        return None
+    def getRelatedContents(self, item, relationship):
+        if relationship == REL_PARENT_GROUP:
+            # Logically speaking, all posts are always flattened.
+            return None
 
-    def getRelatedContents(self, item, relationship):
         if relationship == REL_ASSETS:
             return SimpleAssetsSubDirMixin._getRelatedAssetsContents(
                 self, item)
+
         return FSContentSource.getRelatedContents(self, item, relationship)
 
     def findGroup(self, spec):