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 __future__ import unicode_literals, print_function
# From django.core.paginator # From django.core.paginator
import functools
import logging
from math import ceil from math import ceil
logger = logging.getLogger(__name__)
class Paginator(object): 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.object_list = object_list
self.per_page = per_page self.settings = settings
self.orphans = orphans
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 self._num_pages = self._count = None
def page(self, number): def page(self, number):
@ -18,7 +30,8 @@ class Paginator(object):
top = bottom + self.per_page top = bottom + self.per_page
if top + self.orphans >= self.count: if top + self.orphans >= self.count:
top = 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): def _get_count(self):
"Returns the total number of objects, across all pages." "Returns the total number of objects, across all pages."
@ -45,10 +58,12 @@ class Paginator(object):
class Page(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.object_list = object_list
self.number = number self.number = number
self.paginator = paginator self.paginator = paginator
self.settings = settings
def __repr__(self): def __repr__(self):
return '<Page %s of %s>' % (self.number, self.paginator.num_pages) 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: if self.number == self.paginator.num_pages:
return self.paginator.count return self.paginator.count
return self.number * self.paginator.per_page 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'), 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'),
'AUTHOR_URL': 'author/{slug}.html', 'AUTHOR_URL': 'author/{slug}.html',
'AUTHOR_SAVE_AS': os.path.join('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, 'YEAR_ARCHIVE_SAVE_AS': False,
'MONTH_ARCHIVE_SAVE_AS': False, 'MONTH_ARCHIVE_SAVE_AS': False,
'DAY_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> </article></li>
</ol><!-- /#posts-list --> </ol><!-- /#posts-list -->
<p class="paginator"> <p class="paginator">
<a href="../author/alexis-metaireau.html">&laquo;</a> <a href="../author/alexis-metaireau.html">&laquo;</a>
Page 2 / 3 Page 2 / 3
<a href="../author/alexis-metaireau3.html">&raquo;</a> <a href="../author/alexis-metaireau3.html">&raquo;</a>
</p> </p>
</section><!-- /#content --> </section><!-- /#content -->

View file

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

View file

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

View file

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

View file

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

View file

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