Mercurial > piecrust2
comparison piecrust/data/linker.py @ 247:d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
The `family` object is special in that it's "attached" to the current page, so make an object dedicated to that. It removes special code in `Linker`, and makes it possible to go `family.children` directly to get a page's children (i.e. pages in a directory of the same name).
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 19 Feb 2015 23:33:54 -0800 |
parents | f130365568ff |
children | 311447fe3dd0 |
comparison
equal
deleted
inserted
replaced
242:f130365568ff | 247:d9d5c5de02a8 |
---|---|
5 from piecrust.sources.base import build_pages | 5 from piecrust.sources.base import build_pages |
6 from piecrust.sources.interfaces import IPaginationSource, IListableSource | 6 from piecrust.sources.interfaces import IPaginationSource, IListableSource |
7 | 7 |
8 | 8 |
9 logger = logging.getLogger(__name__) | 9 logger = logging.getLogger(__name__) |
10 | |
11 | |
12 class PageLinkerData(object): | |
13 """ Entry template data to get access to related pages from a given | |
14 root page. | |
15 """ | |
16 def __init__(self, source, page_path): | |
17 self._linker = Linker(source, page_path) | |
18 | |
19 @property | |
20 def siblings(self): | |
21 return self._linker | |
22 | |
23 @property | |
24 def children(self): | |
25 self._linker._load() | |
26 print("GOT ", self._linker._items.keys()) | |
27 if self._linker._self_item is None: | |
28 return None | |
29 return self._linker._self_item.config.get('__linker_child') | |
30 | |
31 @property | |
32 def root(self): | |
33 return self._linker.root | |
34 | |
35 def forpath(self, rel_path): | |
36 return self._linker.forpath(rel_path) | |
10 | 37 |
11 | 38 |
12 class LinkedPageData(PaginationData): | 39 class LinkedPageData(PaginationData): |
13 """ Class whose instances get returned when iterating on a `Linker` | 40 """ Class whose instances get returned when iterating on a `Linker` |
14 or `RecursiveLinker`. It's just like what gets usually returned by | 41 or `RecursiveLinker`. It's just like what gets usually returned by |
75 | 102 |
76 | 103 |
77 class Linker(object): | 104 class Linker(object): |
78 debug_render_doc = """Provides access to sibling and children pages.""" | 105 debug_render_doc = """Provides access to sibling and children pages.""" |
79 | 106 |
80 def __init__(self, source, *, name=None, dir_path=None, page_path=None): | 107 def __init__(self, source, root_page_path, *, name=None, dir_path=None): |
81 self._source = source | 108 self._source = source |
109 self._root_page_path = root_page_path | |
82 self._name = name | 110 self._name = name |
83 self._dir_path = dir_path | 111 self._dir_path = dir_path |
84 self._root_page_path = page_path | |
85 self._items = None | 112 self._items = None |
113 self._self_item = None | |
86 | 114 |
87 self.is_dir = True | 115 self.is_dir = True |
88 self.is_page = False | 116 self.is_page = False |
89 self.is_self = False | 117 self.is_self = False |
90 | 118 |
136 @property | 164 @property |
137 def root(self): | 165 def root(self): |
138 return self.forpath('/') | 166 return self.forpath('/') |
139 | 167 |
140 def forpath(self, rel_path): | 168 def forpath(self, rel_path): |
141 return Linker(self._source, | 169 return Linker(self._source, self._root_page_path, |
142 name='.', dir_path=rel_path, | 170 name='.', dir_path=rel_path) |
143 page_path=self._root_page_path) | |
144 | 171 |
145 def _iterItems(self, max_depth=-1, filter_func=None): | 172 def _iterItems(self, max_depth=-1, filter_func=None): |
146 items = walk_linkers(self, max_depth=max_depth, | 173 items = walk_linkers(self, max_depth=max_depth, |
147 filter_func=filter_func) | 174 filter_func=filter_func) |
148 src = LinkerSource(items, self._source) | 175 src = LinkerSource(items, self._source) |
154 | 181 |
155 is_listable = isinstance(self._source, IListableSource) | 182 is_listable = isinstance(self._source, IListableSource) |
156 if not is_listable: | 183 if not is_listable: |
157 raise Exception("Source '%s' can't be listed." % self._source.name) | 184 raise Exception("Source '%s' can't be listed." % self._source.name) |
158 | 185 |
159 if self._root_page_path is not None: | 186 if self._name is None: |
160 if self._name is None: | 187 self._name = self._source.getBasename(self._root_page_path) |
161 self._name = self._source.getBasename(self._root_page_path) | 188 if self._dir_path is None: |
162 if self._dir_path is None: | 189 self._dir_path = self._source.getDirpath(self._root_page_path) |
163 self._dir_path = self._source.getDirpath(self._root_page_path) | |
164 | 190 |
165 if self._dir_path is None: | 191 if self._dir_path is None: |
166 raise Exception("This linker has no directory to start from.") | 192 raise Exception("This linker has no directory to start from.") |
167 | 193 |
168 items = list(self._source.listPath(self._dir_path)) | 194 items = list(self._source.listPath(self._dir_path)) |
170 with self._source.app.env.page_repository.startBatchGet(): | 196 with self._source.app.env.page_repository.startBatchGet(): |
171 for is_dir, name, data in items: | 197 for is_dir, name, data in items: |
172 # If `is_dir` is true, `data` will be the directory's source | 198 # If `is_dir` is true, `data` will be the directory's source |
173 # path. If not, it will be a page factory. | 199 # path. If not, it will be a page factory. |
174 if is_dir: | 200 if is_dir: |
175 item = Linker(self._source, | 201 item = Linker(self._source, self._root_page_path, |
176 name=name, dir_path=data) | 202 name=name, dir_path=data) |
177 else: | 203 else: |
178 item = data.buildPage() | 204 item = data.buildPage() |
205 is_self = (item.rel_path == self._root_page_path) | |
179 item.config.set('__linker_name', name) | 206 item.config.set('__linker_name', name) |
180 item.config.set('__linker_is_self', | 207 item.config.set('__linker_is_self', is_self) |
181 item.rel_path == self._root_page_path) | 208 if is_self: |
209 self._self_item = item | |
182 | 210 |
183 existing = self._items.get(name) | 211 existing = self._items.get(name) |
184 if existing is None: | 212 if existing is None: |
185 self._items[name] = item | 213 self._items[name] = item |
186 elif is_dir: | 214 elif is_dir: |