diff --git a/docs/settings.rst b/docs/settings.rst
index a4299be6..8ecac7c9 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -479,8 +479,32 @@ Setting name (default value) What does it do?
`DEFAULT_PAGINATION` (``False``) The maximum number of articles to include on a
page, not including orphans. False to disable
pagination.
+`PAGINATION_PATTERNS` A set of patterns that are used to determine advanced
+ pagination output.
================================================ =====================================================
+Using Pagination Patterns
+-------------------------
+
+The ``PAGINATION_PATTERNS`` setting can be used to configure where
+subsequent pages are created. The setting is a sequence of three
+element tuples, where each tuple consists of::
+
+ (minimum page, URL setting, SAVE_AS setting,)
+
+For example, if you wanted the first page to just be ``/``, and the
+second (and subsequent) pages to be ``/page/2/``, you would set
+``PAGINATION_PATTERNS`` as follows::
+
+ PAGINATION_PATTERNS = (
+ (1, '{base_name}/', '{base_name}/index.html'),
+ (2, '{base_name}/page/{number}/', '{base_name}/page/{number}/index.html'),
+ )
+
+This would cause the first page to be written to
+``{base_name}/index.html``, and subsequent ones would be written into
+``page/{number}`` directories.
+
Tag cloud
=========
diff --git a/pelican/paginator.py b/pelican/paginator.py
index 067215c2..df8606ec 100644
--- a/pelican/paginator.py
+++ b/pelican/paginator.py
@@ -1,15 +1,37 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
+import six
# From django.core.paginator
+from collections import namedtuple
+import functools
+import logging
+import os
+
from math import ceil
+logger = logging.getLogger(__name__)
+
+
+PaginationRule = namedtuple(
+ 'PaginationRule',
+ 'min_page URL SAVE_AS',
+)
+
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 +40,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 +68,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 '
- « - 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
- « - Page 3 / 3 + « + Page 3 / 3
{% 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..25f49aeb 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 = os.path.splitext(name)[0] + # 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)