PAGINATION_URL/PAGINATION_SAVE_AS implementation

allows the use of custom urls for pagination similar to *_URLS
This commit is contained in:
Ross McFarland 2012-12-29 09:05:40 -08:00 committed by Nathan Yergler
commit c5eecd23eb
8 changed files with 66 additions and 33 deletions

View file

@ -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 '<Page %s of %s>' % (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'))

View file

@ -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,

View file

@ -142,8 +142,8 @@ as well as <strong>inline markup</strong>.</p>
</article></li>
</ol><!-- /#posts-list -->
<p class="paginator">
<a href="../author/alexis-metaireau.html">&laquo;</a>
Page 2 / 3
<a href="../author/alexis-metaireau.html">&laquo;</a>
Page 2 / 3
<a href="../author/alexis-metaireau3.html">&raquo;</a>
</p>
</section><!-- /#content -->

View file

@ -59,8 +59,8 @@
</article></li>
</ol><!-- /#posts-list -->
<p class="paginator">
<a href="../author/alexis-metaireau2.html">&laquo;</a>
Page 3 / 3
<a href="../author/alexis-metaireau2.html">&laquo;</a>
Page 3 / 3
</p>
</section><!-- /#content -->
<section id="extras" class="body">

View file

@ -140,8 +140,8 @@ YEAH !</p>
</article></li>
</ol><!-- /#posts-list -->
<p class="paginator">
<a href="./index.html">&laquo;</a>
Page 2 / 3
<a href="./index.html">&laquo;</a>
Page 2 / 3
<a href="./index3.html">&raquo;</a>
</p>
</section><!-- /#content -->

View file

@ -59,8 +59,8 @@
</article></li>
</ol><!-- /#posts-list -->
<p class="paginator">
<a href="./index2.html">&laquo;</a>
Page 3 / 3
<a href="./index2.html">&laquo;</a>
Page 3 / 3
</p>
</section><!-- /#content -->
<section id="extras" class="body">

View file

@ -1,15 +1,11 @@
{% if DEFAULT_PAGINATION %}
<p class="paginator">
{% if articles_page.has_previous() %}
{% if articles_page.previous_page_number() == 1 %}
<a href="{{ SITEURL }}/{{ page_name }}.html">&laquo;</a>
{% else %}
<a href="{{ SITEURL }}/{{ page_name }}{{ articles_page.previous_page_number() }}.html">&laquo;</a>
{% endif %}
<a href="{{ SITEURL }}/{{ articles_previous_page.url }}">&laquo;</a>
{% endif %}
Page {{ articles_page.number }} / {{ articles_paginator.num_pages }}
{% if articles_page.has_next() %}
<a href="{{ SITEURL }}/{{ page_name }}{{ articles_page.next_page_number() }}.html">&raquo;</a>
<a href="{{ SITEURL }}/{{ articles_next_page.url }}">&raquo;</a>
{% endif %}
</p>
{% endif %}

View file

@ -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)