Mercurial > piecrust2
annotate piecrust/data/linker.py @ 298:b7ab1b503510
data: Fix incorrect next/previous page URLs in pagination data.
Consolidate splitting an URL between its first URL and its sub page number.
Be careful about the index page's URL not losing its slash.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 11 Mar 2015 23:46:42 -0700 |
parents | 311447fe3dd0 |
children | 2408eb6f4da8 |
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 |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
2 import collections |
242
f130365568ff
internal: Code reorganization to put less stuff in `sources.base`.
Ludovic Chabant <ludovic@chabant.com>
parents:
237
diff
changeset
|
3 from piecrust.data.base import PaginationData |
212
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
4 from piecrust.data.iterators import PageIterator |
242
f130365568ff
internal: Code reorganization to put less stuff in `sources.base`.
Ludovic Chabant <ludovic@chabant.com>
parents:
237
diff
changeset
|
5 from piecrust.sources.base import build_pages |
f130365568ff
internal: Code reorganization to put less stuff in `sources.base`.
Ludovic Chabant <ludovic@chabant.com>
parents:
237
diff
changeset
|
6 from piecrust.sources.interfaces import IPaginationSource, IListableSource |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
7 |
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 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
|
10 |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
11 |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
12 class PageLinkerData(object): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
13 """ Entry template data to get access to related pages from a given |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
14 root page. |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
15 """ |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
16 def __init__(self, source, page_path): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
17 self._linker = Linker(source, page_path) |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
18 |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
19 @property |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
20 def siblings(self): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
21 return self._linker |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
22 |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
23 @property |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
24 def children(self): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
25 self._linker._load() |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
26 if self._linker._self_item is None: |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
27 return None |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
28 return self._linker._self_item.config.get('__linker_child') |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
29 |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
30 @property |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
31 def root(self): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
32 return self._linker.root |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
33 |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
34 def forpath(self, rel_path): |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
35 return self._linker.forpath(rel_path) |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
36 |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
37 |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
38 class LinkedPageData(PaginationData): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
39 """ Class whose instances get returned when iterating on a `Linker` |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
40 or `RecursiveLinker`. It's just like what gets usually returned by |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
41 `Paginator` and other page iterators, but with a few additional data |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
42 like hierarchical data. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
43 """ |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
44 debug_render = ['is_dir', 'is_self'] + PaginationData.debug_render |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
45 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
46 def __init__(self, page): |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
47 super(LinkedPageData, self).__init__(page) |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
48 self.name = page.config.get('__linker_name') |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
49 self.is_self = page.config.get('__linker_is_self') |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
50 self.children = page.config.get('__linker_child') |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
51 self.is_dir = (self.children is not None) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
52 self.is_page = True |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
53 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
54 self.mapLoader('*', self._linkerChildLoader) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
55 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
56 def _linkerChildLoader(self, name): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
57 return getattr(self.children, name) |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
58 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
59 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
60 class LinkedPageDataBuilderIterator(object): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
61 """ Iterator that builds `LinkedPageData` out of pages. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
62 """ |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
63 def __init__(self, it): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
64 self.it = it |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
65 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
66 def __iter__(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
67 for item in self.it: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
68 yield LinkedPageData(item) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
69 |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
70 |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
71 class LinkerSource(IPaginationSource): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
72 """ Source iterator that returns pages given by `Linker`. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
73 """ |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
74 def __init__(self, pages, orig_source): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
75 self._pages = list(pages) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
76 self._orig_source = None |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
77 if isinstance(orig_source, IPaginationSource): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
78 self._orig_source = orig_source |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
79 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
80 def getItemsPerPage(self): |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
81 raise NotImplementedError() |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
82 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
83 def getSourceIterator(self): |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
84 return self._pages |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
85 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
86 def getSorterIterator(self, it): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
87 # We don't want to sort the pages -- we expect the original source |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
88 # to return hierarchical items in the order it wants already. |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
89 return None |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
90 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
91 def getTailIterator(self, it): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
92 return LinkedPageDataBuilderIterator(it) |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
93 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
94 def getPaginationFilter(self, page): |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
95 return None |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
96 |
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
97 def getSettingAccessor(self): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
98 if self._orig_source: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
99 return self._orig_source.getSettingAccessor() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
100 return None |
212
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
101 |
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
102 |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
103 class Linker(object): |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
104 debug_render_doc = """Provides access to sibling and children pages.""" |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
105 |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
106 def __init__(self, source, root_page_path, *, name=None, dir_path=None): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
107 self._source = source |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
108 self._root_page_path = root_page_path |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
109 self._name = name |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
110 self._dir_path = dir_path |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
111 self._items = None |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
112 self._self_item = None |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
113 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
114 self.is_dir = True |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
115 self.is_page = False |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
116 self.is_self = False |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
117 |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
118 def __iter__(self): |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
119 return iter(self.pages) |
212
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
120 |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
121 def __getattr__(self, name): |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
122 self._load() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
123 try: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
124 item = self._items[name] |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
125 except KeyError: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
126 raise AttributeError() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
127 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
128 if isinstance(item, Linker): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
129 return item |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
130 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
131 return LinkedPageData(item) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
132 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
133 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
134 def name(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
135 if self._name is None: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
136 self._load() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
137 return self._name |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
138 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
139 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
140 def children(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
141 return self._iterItems(0) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
142 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
143 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
144 def pages(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
145 return self._iterItems(0, filter_page_items) |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
146 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
147 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
148 def directories(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
149 return self._iterItems(0, filter_directory_items) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
150 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
151 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
152 def all(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
153 return self._iterItems() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
154 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
155 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
156 def allpages(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
157 return self._iterItems(-1, filter_page_items) |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
158 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
159 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
160 def alldirectories(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
161 return self._iterItems(-1, filter_directory_items) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
162 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
163 @property |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
164 def root(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
165 return self.forpath('/') |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
166 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
167 def forpath(self, rel_path): |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
168 return Linker(self._source, self._root_page_path, |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
169 name='.', dir_path=rel_path) |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
170 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
171 def _iterItems(self, max_depth=-1, filter_func=None): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
172 items = walk_linkers(self, max_depth=max_depth, |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
173 filter_func=filter_func) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
174 src = LinkerSource(items, self._source) |
227
d6d0e4976beb
data: Make the `Linekr` use the new `getSettingAccessor` API.
Ludovic Chabant <ludovic@chabant.com>
parents:
212
diff
changeset
|
175 return PageIterator(src) |
212
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
176 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
177 def _load(self): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
178 if self._items is not None: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
179 return |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
180 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
181 is_listable = isinstance(self._source, IListableSource) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
182 if not is_listable: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
183 raise Exception("Source '%s' can't be listed." % self._source.name) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
184 |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
185 if self._name is None: |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
186 self._name = self._source.getBasename(self._root_page_path) |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
187 if self._dir_path is None: |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
188 self._dir_path = self._source.getDirpath(self._root_page_path) |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
189 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
190 if self._dir_path is None: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
191 raise Exception("This linker has no directory to start from.") |
212
701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
172
diff
changeset
|
192 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
193 items = list(self._source.listPath(self._dir_path)) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
194 self._items = collections.OrderedDict() |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
195 with self._source.app.env.page_repository.startBatchGet(): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
196 for is_dir, name, data in items: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
197 # If `is_dir` is true, `data` will be the directory's source |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
198 # path. If not, it will be a page factory. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
199 if is_dir: |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
200 item = Linker(self._source, self._root_page_path, |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
201 name=name, dir_path=data) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
202 else: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
203 item = data.buildPage() |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
204 is_self = (item.rel_path == self._root_page_path) |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
205 item.config.set('__linker_name', name) |
247
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
206 item.config.set('__linker_is_self', is_self) |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
207 if is_self: |
d9d5c5de02a8
data: Add a top level wrapper for `Linker`.
Ludovic Chabant <ludovic@chabant.com>
parents:
242
diff
changeset
|
208 self._self_item = item |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
209 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
210 existing = self._items.get(name) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
211 if existing is None: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
212 self._items[name] = item |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
213 elif is_dir: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
214 # The current item is a directory. The existing item |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
215 # should be a page. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
216 existing.config.set('__linker_child', item) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
217 else: |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
218 # The current item is a page. The existing item should |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
219 # be a directory. |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
220 item.config.set('__linker_child', existing) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
221 self._items[name] = item |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
222 |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
223 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
224 def filter_page_items(item): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
225 return not isinstance(item, Linker) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
226 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
227 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
228 def filter_directory_items(item): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
229 return isinstance(item, linker) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
230 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
231 |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
232 def walk_linkers(linker, depth=0, max_depth=-1, filter_func=None): |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
233 linker._load() |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
234 for item in linker._items.values(): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
235 if not filter_func or filter_func(item): |
172
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
236 yield item |
4fc1d306046b
linker: Actually implement the `Linker` class, and use it in the page data.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
237 |
237
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
238 if (isinstance(item, Linker) and |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
239 (max_depth < 0 or depth + 1 <= max_depth)): |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
240 yield from walk_linkers(item, depth + 1, max_depth) |
879fe1457e48
data: `Linker` refactor.
Ludovic Chabant <ludovic@chabant.com>
parents:
227
diff
changeset
|
241 |