diff --git a/pelican/paginator.py b/pelican/paginator.py index 067215c2..5fc6357e 100644 --- a/pelican/paginator.py +++ b/pelican/paginator.py @@ -2,14 +2,26 @@ from __future__ import unicode_literals, print_function # From django.core.paginator +import functools +import logging + from math import ceil +logger = logging.getLogger(__name__) class Paginator(object): - def __init__(self, object_list, per_page, orphans=0): + def __init__(self, name, object_list, settings): + self.name = name self.object_list = object_list - self.per_page = per_page - self.orphans = orphans + self.settings = settings + + if settings.get('DEFAULT_PAGINATION'): + self.per_page = settings.get('DEFAULT_PAGINATION') + self.orphans = settings.get('DEFAULT_ORPHANS') + else: + self.per_page = len(object_list) + self.orphans = 0 + self._num_pages = self._count = None def page(self, number): @@ -18,7 +30,8 @@ class Paginator(object): top = bottom + self.per_page if top + self.orphans >= self.count: top = self.count - return Page(self.object_list[bottom:top], number, self) + return Page(self.name, self.object_list[bottom:top], number, self, + self.settings) def _get_count(self): "Returns the total number of objects, across all pages." @@ -45,10 +58,12 @@ class Paginator(object): class Page(object): - def __init__(self, object_list, number, paginator): + def __init__(self, name, object_list, number, paginator, settings): + self.name = name self.object_list = object_list self.number = number self.paginator = paginator + self.settings = settings def __repr__(self): return '' % (self.number, self.paginator.num_pages) @@ -87,3 +102,22 @@ class Page(object): if self.number == self.paginator.num_pages: return self.paginator.count return self.number * self.paginator.per_page + + def _from_settings(self, key): + """Returns URL information as defined in settings. Similar to + URLWrapper._from_settings, but specialized to deal with pagination + logic.""" + setting = "%s_%s" % ('PAGINATION', key) + value = self.settings[setting] + if not isinstance(value, basestring): + logger.warning(u'%s is set to %s' % (setting, value)) + return value + else: + context = self.__dict__ + if self.number == 1: + # no page numbers on the first page + context['number'] = '' + return unicode(value).format(**context) + + url = property(functools.partial(_from_settings, key='URL')) + save_as = property(functools.partial(_from_settings, key='SAVE_AS')) diff --git a/pelican/settings.py b/pelican/settings.py index 01203504..b65a6df7 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -73,6 +73,8 @@ DEFAULT_CONFIG = { 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'), 'AUTHOR_URL': 'author/{slug}.html', 'AUTHOR_SAVE_AS': os.path.join('author', '{slug}.html'), + 'PAGINATION_URL': '{name}{number}.html', + 'PAGINATION_SAVE_AS': '{name}{number}.html', 'YEAR_ARCHIVE_SAVE_AS': False, 'MONTH_ARCHIVE_SAVE_AS': False, 'DAY_ARCHIVE_SAVE_AS': False, diff --git a/pelican/tests/output/custom/author/alexis-metaireau2.html b/pelican/tests/output/custom/author/alexis-metaireau2.html index 9f4a31e8..5d92303c 100644 --- a/pelican/tests/output/custom/author/alexis-metaireau2.html +++ b/pelican/tests/output/custom/author/alexis-metaireau2.html @@ -142,8 +142,8 @@ as well as inline markup.

- « - Page 2 / 3 + « + Page 2 / 3 »

diff --git a/pelican/tests/output/custom/author/alexis-metaireau3.html b/pelican/tests/output/custom/author/alexis-metaireau3.html index 4eda0b62..64468725 100644 --- a/pelican/tests/output/custom/author/alexis-metaireau3.html +++ b/pelican/tests/output/custom/author/alexis-metaireau3.html @@ -59,8 +59,8 @@

- « - Page 3 / 3 + « + Page 3 / 3

diff --git a/pelican/tests/output/custom/index2.html b/pelican/tests/output/custom/index2.html index b8e2ac1a..7de87a34 100644 --- a/pelican/tests/output/custom/index2.html +++ b/pelican/tests/output/custom/index2.html @@ -140,8 +140,8 @@ YEAH !

- « - Page 2 / 3 + « + Page 2 / 3 »

diff --git a/pelican/tests/output/custom/index3.html b/pelican/tests/output/custom/index3.html index cf285ea2..18435df8 100644 --- a/pelican/tests/output/custom/index3.html +++ b/pelican/tests/output/custom/index3.html @@ -59,8 +59,8 @@

- « - Page 3 / 3 + « + Page 3 / 3

diff --git a/pelican/themes/simple/templates/pagination.html b/pelican/themes/simple/templates/pagination.html index 83c587ac..4219a5c3 100644 --- a/pelican/themes/simple/templates/pagination.html +++ b/pelican/themes/simple/templates/pagination.html @@ -1,15 +1,11 @@ {% if DEFAULT_PAGINATION %}

{% if articles_page.has_previous() %} - {% if articles_page.previous_page_number() == 1 %} - « - {% else %} - « - {% endif %} + « {% endif %} Page {{ articles_page.number }} / {{ articles_paginator.num_pages }} {% if articles_page.has_next() %} - » + » {% endif %}

{% endif %} diff --git a/pelican/writers.py b/pelican/writers.py index fe37b25d..1113a5ba 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -150,36 +150,37 @@ class Writer(object): # check paginated paginated = paginated or {} if paginated: + name_root, ext = os.path.splitext(name) + # pagination needed, init paginators paginators = {} for key in paginated.keys(): object_list = paginated[key] - if self.settings['DEFAULT_PAGINATION']: - paginators[key] = Paginator(object_list, - self.settings['DEFAULT_PAGINATION'], - self.settings['DEFAULT_ORPHANS']) - else: - paginators[key] = Paginator(object_list, len(object_list)) + paginators[key] = Paginator( + name_root, + object_list, + self.settings, + ) # generated pages, and write - name_root, ext = os.path.splitext(name) for page_num in range(list(paginators.values())[0].num_pages): paginated_localcontext = localcontext.copy() for key in paginators.keys(): paginator = paginators[key] + previous_page = paginator.page(page_num) \ + if page_num > 0 else None page = paginator.page(page_num + 1) + next_page = paginator.page(page_num + 2) \ + if page_num + 1 < paginator.num_pages else None paginated_localcontext.update( {'%s_paginator' % key: paginator, - '%s_page' % key: page}) - if page_num > 0: - paginated_name = '%s%s%s' % ( - name_root, page_num + 1, ext) - else: - paginated_name = name + '%s_page' % key: page, + '%s_previous_page' % key: previous_page, + '%s_next_page' % key: next_page}) _write_file(template, paginated_localcontext, self.output_path, - paginated_name) + page.save_as) else: # no pagination _write_file(template, localcontext, self.output_path, name)