Mercurial > piecrust2
changeset 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 | 1f22d4b10fef |
children | 8140ff806258 |
files | piecrust/data/builder.py piecrust/data/paginator.py piecrust/templating/jinjaengine.py tests/bakes/test_pagination.bake tests/test_data_paginator.py |
diffstat | 5 files changed, 85 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/data/builder.py Fri Apr 17 16:08:23 2015 -0700 +++ b/piecrust/data/builder.py Fri Apr 17 16:09:30 2015 -0700 @@ -34,7 +34,7 @@ pc_data = PieCrustData() pgn_source = ctx.pagination_source or get_default_pagination_source(page) - paginator = Paginator(page, pgn_source, first_uri, ctx.page_num, + paginator = Paginator(page, pgn_source, ctx.page_num, ctx.pagination_filter) assetor = Assetor(page, first_uri) linker = PageLinkerData(page.source, page.rel_path)
--- a/piecrust/data/paginator.py Fri Apr 17 16:08:23 2015 -0700 +++ b/piecrust/data/paginator.py Fri Apr 17 16:09:30 2015 -0700 @@ -10,23 +10,25 @@ class Paginator(object): - debug_render = ['has_more', 'items', 'has_items', 'items_per_page', - 'items_this_page', 'prev_page_number', 'this_page_number', - 'next_page_number', 'prev_page', 'next_page', - 'total_item_count', 'total_page_count', - 'next_item', 'prev_item'] - debug_render_invoke = ['has_more', 'items', 'has_items', 'items_per_page', - 'items_this_page', 'prev_page_number', 'this_page_number', - 'next_page_number', 'prev_page', 'next_page', - 'total_item_count', 'total_page_count', - 'next_item', 'prev_item'] + debug_render = [ + 'has_more', 'items', 'has_items', 'items_per_page', + 'items_this_page', 'prev_page_number', 'this_page_number', + 'next_page_number', 'prev_page', 'next_page', + 'total_item_count', 'total_page_count', + 'next_item', 'prev_item'] + debug_render_invoke = [ + 'has_more', 'items', 'has_items', 'items_per_page', + 'items_this_page', 'prev_page_number', 'this_page_number', + 'next_page_number', 'prev_page', 'next_page', + 'total_item_count', 'total_page_count', + 'next_item', 'prev_item'] - def __init__(self, page, source, uri, page_num=1, pgn_filter=None, - items_per_page=-1): + def __init__(self, page, source, page_num=1, pgn_filter=None, + items_per_page=-1): self._parent_page = page self._source = source - self._uri = uri self._page_num = page_num + self._route = None self._iterator = None self._pgn_filter = pgn_filter self._items_per_page = items_per_page @@ -185,11 +187,13 @@ return if self._source is None: - raise Exception("Can't load pagination data: no source has been defined.") + raise Exception("Can't load pagination data: no source has " + "been defined.") pag_filter = self._getPaginationFilter() offset = (self._page_num - 1) * self.items_per_page - self._iterator = PageIterator(self._source, + self._iterator = PageIterator( + self._source, current_page=self._parent_page, pagination_filter=pag_filter, offset=offset, limit=self.items_per_page, @@ -210,12 +214,17 @@ return f def _getPageUri(self, index): - uri = self._uri - if index > 1: - if len(uri) > 0 and not uri.endswith('/'): - uri += '/' - uri += str(index) - return uri + if self._route is None: + app = self._source.app + self._route = app.getRoute(self._parent_page.source.name, + self._parent_page.source_metadata) + if self._route is None: + raise Exception("Can't get route for page: %s" % + self._parent_page.path) + + return self._route.getUri(self._parent_page.source_metadata, + provider=self._parent_page, + sub_num=index) def _onIteration(self): if self._parent_page is not None and not self._pgn_set_on_ctx:
--- a/piecrust/templating/jinjaengine.py Fri Apr 17 16:08:23 2015 -0700 +++ b/piecrust/templating/jinjaengine.py Fri Apr 17 16:09:30 2015 -0700 @@ -179,9 +179,9 @@ raise Exception("Can't paginate when no page has been pushed " "on the execution stack.") first_uri, _ = split_sub_uri(self.app, cpi.render_ctx.uri) - return Paginator(cpi.page, value, first_uri, - page_num=cpi.render_ctx.page_num, - items_per_page=items_per_page) + return Paginator(cpi.page, value, + page_num=cpi.render_ctx.page_num, + items_per_page=items_per_page) def _formatWith(self, value, format_name): return format_text(self.app, format_name, value)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/bakes/test_pagination.bake Fri Apr 17 16:09:30 2015 -0700 @@ -0,0 +1,41 @@ +--- +config: + site: + posts_per_page: 3 + pagination_suffix: /page%num% +in: + posts/2015-03-01_post01.md: "---\ntitle: Post 01\n---\n" + posts/2015-03-02_post02.md: "---\ntitle: Post 02\n---\n" + posts/2015-03-03_post03.md: "---\ntitle: Post 03\n---\n" + posts/2015-03-04_post04.md: "---\ntitle: Post 04\n---\n" + posts/2015-03-05_post05.md: "---\ntitle: Post 05\n---\n" + posts/2015-03-06_post06.md: "---\ntitle: Post 06\n---\n" + posts/2015-03-07_post07.md: "---\ntitle: Post 07\n---\n" + pages/_index.md: '' + pages/foo.md: | + {%- for p in pagination.items -%} + {{p.url}} {{p.title}} + {% endfor -%} + {{pagination.prev_page}} + {{pagination.this_page}} + {{pagination.next_page}} +outfiles: + foo.html: | + /2015/03/07/post07.html Post 07 + /2015/03/06/post06.html Post 06 + /2015/03/05/post05.html Post 05 + None + /foo.html + /foo/page2.html + foo/page2.html: | + /2015/03/04/post04.html Post 04 + /2015/03/03/post03.html Post 03 + /2015/03/02/post02.html Post 02 + /foo.html + /foo/page2.html + /foo/page3.html + foo/page3.html: | + /2015/03/01/post01.html Post 01 + /foo/page2.html + /foo/page3.html + None
--- a/tests/test_data_paginator.py Fri Apr 17 16:08:23 2015 -0700 +++ b/tests/test_data_paginator.py Fri Apr 17 16:09:30 2015 -0700 @@ -44,8 +44,17 @@ ('blog', 3, 14) ]) def test_paginator(uri, page_num, count): + def _mock_get_uri(index): + res = uri + if index > 1: + if res != '' and not res.endswith('/'): + res += '/' + res += '%d' % index + return res + source = MockSource(count) - p = Paginator(None, source, uri, page_num) + p = Paginator(None, source, page_num) + p._getPageUri = _mock_get_uri if count <= 5: # All posts fit on the page