From c5eecd23eb3d7498210701c278cbb9365cfb45ff Mon Sep 17 00:00:00 2001
From: Ross McFarland
Date: Sat, 29 Dec 2012 09:05:40 -0800
Subject: [PATCH] PAGINATION_URL/PAGINATION_SAVE_AS implementation
allows the use of custom urls for pagination similar to *_URLS
---
pelican/paginator.py | 44 ++++++++++++++++---
pelican/settings.py | 2 +
.../custom/author/alexis-metaireau2.html | 4 +-
.../custom/author/alexis-metaireau3.html | 4 +-
pelican/tests/output/custom/index2.html | 4 +-
pelican/tests/output/custom/index3.html | 4 +-
.../themes/simple/templates/pagination.html | 8 +---
pelican/writers.py | 29 ++++++------
8 files changed, 66 insertions(+), 33 deletions(-)
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)