annotate piecrust/data/linker.py @ 966:cc55740860de

data: Delay loading page configuration and datetimes.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 07 Oct 2017 12:32:48 -0700
parents d9059257743c
children 84fc72a17f7a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
172
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
1 import logging
440
32c7c2d219d2 performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents: 411
diff changeset
2 from piecrust.data.paginationdata import PaginationData
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
3 from piecrust.sources.base import (
862
fddaf43424e2 refactor: Get the page assets to work again in the server.
Ludovic Chabant <ludovic@chabant.com>
parents: 854
diff changeset
4 REL_LOGICAL_PARENT_ITEM, REL_LOGICAl_CHILD_GROUP)
172
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
5
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
6
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
7 logger = logging.getLogger(__name__)
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
8
4fc1d306046b linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
9
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
10 _unloaded = object()
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
11
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
12
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
13 class Linker:
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
14 """ A template-exposed data class that lets the user navigate the
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
15 logical hierarchy of pages in a page source.
247
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
16 """
408
fd8e39254da0 debug: Better debug info output for iterators, providers, and linkers.
Ludovic Chabant <ludovic@chabant.com>
parents: 404
diff changeset
17 debug_render = ['parent', 'ancestors', 'siblings', 'children', 'root',
fd8e39254da0 debug: Better debug info output for iterators, providers, and linkers.
Ludovic Chabant <ludovic@chabant.com>
parents: 404
diff changeset
18 'forpath']
590
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
19 debug_render_invoke = ['parent', 'ancestors', 'siblings', 'children',
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
20 'root']
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
21 debug_render_redirect = {
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 590
diff changeset
22 'ancestors': '_debugRenderAncestors',
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 590
diff changeset
23 'siblings': '_debugRenderSiblings',
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 590
diff changeset
24 'children': '_debugRenderChildren',
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 590
diff changeset
25 'root': '_debugRenderRoot'}
408
fd8e39254da0 debug: Better debug info output for iterators, providers, and linkers.
Ludovic Chabant <ludovic@chabant.com>
parents: 404
diff changeset
26
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
27 def __init__(self, source, content_item):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
28 self._source = source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
29 self._content_item = content_item
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
30
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
31 self._parent_group = _unloaded
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
32 self._ancestors = None
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
33 self._siblings = None
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
34 self._children = None
404
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
35
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
36 @property
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
37 def parent(self):
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
38 a = self.ancestors
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
39 if a:
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
40 return a[0]
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
41 return None
404
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
42
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
43 @property
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
44 def ancestors(self):
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
45 if self._ancestors is None:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
46 self._ensureParentGroup()
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
47
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
48 src = self._source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
49 app = src.app
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
50
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
51 cur_group = self._parent_group
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
52 self._ancestors = []
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
53 while cur_group:
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
54 pi = src.getRelatedContents(cur_group,
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
55 REL_LOGICAL_PARENT_ITEM)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
56 if pi is not None:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
57 pipage = app.getPage(src, pi)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
58 self._ancestors.append(PaginationData(pipage))
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
59 cur_group = src.getParentGroup(pi)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
60 else:
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
61 break
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
62 return self._ancestors
247
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
63
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
64 @property
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
65 def siblings(self):
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
66 if self._siblings is None:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
67 self._ensureParentGroup()
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
68
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
69 src = self._source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
70 app = src.app
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
71
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
72 self._siblings = []
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
73 for i in src.getContents(self._parent_group):
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
74 if not i.is_group:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
75 ipage = app.getPage(src, i)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
76 self._siblings.append(PaginationData(ipage))
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
77 return self._siblings
247
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
78
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
79 @property
d9d5c5de02a8 data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents: 242
diff changeset
80 def children(self):
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
81 if self._children is None:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
82 src = self._source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
83 app = src.app
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
84
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
85 self._children = []
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
86 child_group = src.getRelatedContents(self._content_item,
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
87 REL_LOGICAl_CHILD_GROUP)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
88 if child_group:
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
89 for i in src.getContents(child_group):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
90 ipage = app.getPage(src, i)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
91 self._children.append(PaginationData(ipage))
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 853
diff changeset
92 return self._children
404
27b10024f8d8 linker: Add ability to return the parent and ancestors of a page.
Ludovic Chabant <ludovic@chabant.com>
parents: 402
diff changeset
93
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
94 def forpath(self, path):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
95 # TODO: generalize this for sources that aren't file-system based.
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
96 item = self._source.findContent({'slug': path})
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
97 return Linker(self._source, item)
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
98
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
99 def childrenof(self, path):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
100 # TODO: generalize this for sources that aren't file-system based.
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
101 src = self._source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
102 app = src.app
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
103 group = src.findGroup(path)
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
104 if group is not None:
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
105 for i in src.getContents(group):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
106 if not i.is_group:
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
107 ipage = app.getPage(src, i)
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
108 yield PaginationData(ipage)
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
109 return None
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
110
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
111 def _ensureParentGroup(self):
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
112 if self._parent_group is _unloaded:
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
113 src = self._source
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
114 item = self._content_item
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
115 self._parent_group = src.getParentGroup(item)
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
116
590
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
117 def _debugRenderAncestors(self):
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
118 return [i.title for i in self.ancestors]
590
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
119
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
120 def _debugRenderSiblings(self):
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
121 return [i.title for i in self.siblings]
590
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
122
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
123 def _debugRenderChildren(self):
866
d9059257743c refactor: Make the linker work again.
Ludovic Chabant <ludovic@chabant.com>
parents: 862
diff changeset
124 return [i.title for i in self.children]
590
3cca1f6bd610 debug: Fix how the linker shows children/siblings/etc. in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 518
diff changeset
125