comparison piecrust/data/paginator.py @ 352:498a917cd2d4

pagination: Make pagination use routes to generate proper URLs. This fixes incorrect URLs when using custom sub-page suffixes, for instance. Add tests.
author Ludovic Chabant <ludovic@chabant.com>
date Fri, 17 Apr 2015 16:09:30 -0700
parents eb958151c8dc
children 4b1019bb2533
comparison
equal deleted inserted replaced
351:1f22d4b10fef 352:498a917cd2d4
8 8
9 logger = logging.getLogger(__name__) 9 logger = logging.getLogger(__name__)
10 10
11 11
12 class Paginator(object): 12 class Paginator(object):
13 debug_render = ['has_more', 'items', 'has_items', 'items_per_page', 13 debug_render = [
14 'items_this_page', 'prev_page_number', 'this_page_number', 14 'has_more', 'items', 'has_items', 'items_per_page',
15 'next_page_number', 'prev_page', 'next_page', 15 'items_this_page', 'prev_page_number', 'this_page_number',
16 'total_item_count', 'total_page_count', 16 'next_page_number', 'prev_page', 'next_page',
17 'next_item', 'prev_item'] 17 'total_item_count', 'total_page_count',
18 debug_render_invoke = ['has_more', 'items', 'has_items', 'items_per_page', 18 'next_item', 'prev_item']
19 'items_this_page', 'prev_page_number', 'this_page_number', 19 debug_render_invoke = [
20 'next_page_number', 'prev_page', 'next_page', 20 'has_more', 'items', 'has_items', 'items_per_page',
21 'total_item_count', 'total_page_count', 21 'items_this_page', 'prev_page_number', 'this_page_number',
22 'next_item', 'prev_item'] 22 'next_page_number', 'prev_page', 'next_page',
23 23 'total_item_count', 'total_page_count',
24 def __init__(self, page, source, uri, page_num=1, pgn_filter=None, 24 'next_item', 'prev_item']
25 items_per_page=-1): 25
26 def __init__(self, page, source, page_num=1, pgn_filter=None,
27 items_per_page=-1):
26 self._parent_page = page 28 self._parent_page = page
27 self._source = source 29 self._source = source
28 self._uri = uri
29 self._page_num = page_num 30 self._page_num = page_num
31 self._route = None
30 self._iterator = None 32 self._iterator = None
31 self._pgn_filter = pgn_filter 33 self._pgn_filter = pgn_filter
32 self._items_per_page = items_per_page 34 self._items_per_page = items_per_page
33 self._pgn_set_on_ctx = False 35 self._pgn_set_on_ctx = False
34 36
183 def _load(self): 185 def _load(self):
184 if self._iterator is not None: 186 if self._iterator is not None:
185 return 187 return
186 188
187 if self._source is None: 189 if self._source is None:
188 raise Exception("Can't load pagination data: no source has been defined.") 190 raise Exception("Can't load pagination data: no source has "
191 "been defined.")
189 192
190 pag_filter = self._getPaginationFilter() 193 pag_filter = self._getPaginationFilter()
191 offset = (self._page_num - 1) * self.items_per_page 194 offset = (self._page_num - 1) * self.items_per_page
192 self._iterator = PageIterator(self._source, 195 self._iterator = PageIterator(
196 self._source,
193 current_page=self._parent_page, 197 current_page=self._parent_page,
194 pagination_filter=pag_filter, 198 pagination_filter=pag_filter,
195 offset=offset, limit=self.items_per_page, 199 offset=offset, limit=self.items_per_page,
196 locked=True) 200 locked=True)
197 self._iterator._iter_event += self._onIteration 201 self._iterator._iter_event += self._onIteration
208 f.addClause(sf.root_clause) 212 f.addClause(sf.root_clause)
209 213
210 return f 214 return f
211 215
212 def _getPageUri(self, index): 216 def _getPageUri(self, index):
213 uri = self._uri 217 if self._route is None:
214 if index > 1: 218 app = self._source.app
215 if len(uri) > 0 and not uri.endswith('/'): 219 self._route = app.getRoute(self._parent_page.source.name,
216 uri += '/' 220 self._parent_page.source_metadata)
217 uri += str(index) 221 if self._route is None:
218 return uri 222 raise Exception("Can't get route for page: %s" %
223 self._parent_page.path)
224
225 return self._route.getUri(self._parent_page.source_metadata,
226 provider=self._parent_page,
227 sub_num=index)
219 228
220 def _onIteration(self): 229 def _onIteration(self):
221 if self._parent_page is not None and not self._pgn_set_on_ctx: 230 if self._parent_page is not None and not self._pgn_set_on_ctx:
222 eis = self._parent_page.app.env.exec_info_stack 231 eis = self._parent_page.app.env.exec_info_stack
223 eis.current_page_info.render_ctx.setPagination(self) 232 eis.current_page_info.render_ctx.setPagination(self)