From d272896adfe5bbd996b726fcf5ee926578784479 Mon Sep 17 00:00:00 2001 From: Laureline Guerin Date: Tue, 15 Feb 2011 14:36:55 +0100 Subject: [PATCH] Pagination - refactoring --- pelican/__init__.py | 2 +- pelican/generators.py | 62 +++++++++---------------------------------- pelican/writers.py | 56 ++++++++++++++++++++++++++++++-------- 3 files changed, 59 insertions(+), 61 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index f599cc46..8114cae8 100755 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -82,7 +82,7 @@ class Pelican(object): return generators def get_writer(self): - return Writer(self.output_path) + return Writer(self.output_path, settings=self.settings) diff --git a/pelican/generators.py b/pelican/generators.py index 0279bda3..94f1a21c 100755 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -12,7 +12,6 @@ from jinja2.exceptions import TemplateNotFound from pelican.utils import copytree, get_relative_path, process_translations, open from pelican.contents import Article, Page, is_valid_content from pelican.readers import read_file -from pelican.paginator import Paginator _TEMPLATES = ('index', 'tag', 'tags', 'article', 'category', 'categories', 'archives', 'page') @@ -143,61 +142,26 @@ class ArticlesGenerator(Generator): category=article.category) for template in _DIRECT_TEMPLATES: - if self.settings.get('WITH_PAGINATION') and template in _PAGINATED_DIRECT_TEMPLATES: - articles_paginator = Paginator(self.articles, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - dates_paginator = Paginator(self.dates, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - for page_num in range(articles_paginator.num_pages): - write('%s%s.html' % (template, '%s' % (page_num > 0 and page_num+1 or '')), - templates[template], self.context, blog=True, - articles_paginator=articles_paginator, articles_page=articles_paginator.page(page_num+1), - dates_paginator=dates_paginator, dates_page=dates_paginator.page(page_num+1), - page_name='index') - else: - write('%s.html' % template, templates[template], self.context, - blog=True) + paginated = {} + if template in _PAGINATED_DIRECT_TEMPLATES: + paginated = {'articles': self.articles, 'dates': self.dates} + write('%s.html' % template, templates[template], self.context, + blog=True, paginated=paginated, page_name=template) # and subfolders after that for tag, articles in self.tags.items(): dates = [article for article in self.dates if article in articles] - if self.settings.get('WITH_PAGINATION'): - articles_paginator = Paginator(articles, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - dates_paginator = Paginator(dates, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - for page_num in range(articles_paginator.num_pages): - write('tag/%s%s.html' % (tag, '%s' % (page_num > 0 and page_num+1 or '')), - templates['tag'], self.context, tag=tag, articles=articles, dates=dates, - articles_paginator=articles_paginator, articles_page=articles_paginator.page(page_num+1), - dates_paginator=dates_paginator, dates_page=dates_paginator.page(page_num+1), - page_name='tag/%s'%tag) - else: - write('tag/%s.html' % tag, templates['tag'], self.context, - tag=tag, articles=articles, dates=dates) + write('tag/%s.html' % tag, templates['tag'], self.context, + tag=tag, articles=articles, dates=dates, + paginated={'articles': articles, 'dates': dates}, + page_name='tag/%s'%tag) for cat, articles in self.categories: dates = [article for article in self.dates if article in articles] - if self.settings.get('WITH_PAGINATION'): - articles_paginator = Paginator(articles, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - dates_paginator = Paginator(dates, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) - for page_num in range(articles_paginator.num_pages): - write('category/%s%s.html' % (cat, '%s' % (page_num > 0 and page_num+1 or '')), - templates['category'], self.context, category=cat, articles=articles, dates=dates, - articles_paginator=articles_paginator, articles_page=articles_paginator.page(page_num+1), - dates_paginator=dates_paginator, dates_page=dates_paginator.page(page_num+1), - page_name='category/%s' % cat) - else: - write('category/%s.html' % cat, templates['category'], self.context, - category=cat, articles=articles, dates=dates) + write('category/%s.html' % cat, templates['category'], self.context, + category=cat, articles=articles, dates=dates, + paginated={'articles': articles, 'dates': dates}, + page_name='category/%s' % cat) def generate_context(self): """change the context""" diff --git a/pelican/writers.py b/pelican/writers.py index ea53aead..9f3779d4 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -7,13 +7,15 @@ import locale from feedgenerator import Atom1Feed, Rss201rev2Feed from pelican.utils import get_relative_path +from pelican.paginator import Paginator class Writer(object): - def __init__(self, output_path): + def __init__(self, output_path, settings=None): self.output_path = output_path self.reminder = dict() + self.settings = settings or {} def _create_new_feed(self, feed_type, context): feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed @@ -74,15 +76,29 @@ class Writer(object): locale.setlocale(locale.LC_ALL, old_locale) def write_file(self, name, template, context, relative_urls=True, - **kwargs): + paginated=None, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones + :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param **kwargs: additional variables to pass to the templates """ + + def _write_file(template, localcontext, output_path, name): + """Render the template write the file.""" + output = template.render(localcontext) + filename = os.sep.join((output_path, name)) + try: + os.makedirs(os.path.dirname(filename)) + except Exception: + pass + with open(filename, 'w', encoding='utf-8') as f: + f.write(output) + print u' [ok] writing %s' % filename + localcontext = context.copy() if relative_urls: localcontext['SITEURL'] = get_relative_path(name) @@ -90,15 +106,33 @@ class Writer(object): localcontext.update(kwargs) self.update_context_contents(name, localcontext) - output = template.render(localcontext) - filename = os.sep.join((self.output_path, name)) - try: - os.makedirs(os.path.dirname(filename)) - except Exception: - pass - with open(filename, 'w', encoding='utf-8') as f: - f.write(output) - print u' [ok] writing %s' % filename + # check paginated + paginated = paginated or {} + if self.settings.get('WITH_PAGINATION') and paginated: + # pagination needed, init paginators + paginators = {} + for key in paginated.iterkeys(): + object_list = paginated[key] + paginators[key] = Paginator(object_list, + self.settings.get('DEFAULT_PAGINATION'), + self.settings.get('DEFAULT_ORPHANS')) + # generated pages, and write + for page_num in range(paginators.values()[0].num_pages): + paginated_localcontext = localcontext.copy() + paginated_name = name + for key in paginators.iterkeys(): + paginator = paginators[key] + page = paginator.page(page_num+1) + paginated_localcontext.update({'%s_paginator' % key: paginator, + '%s_page' % key: page}) + if page_num > 0: + # FIXME file extension + paginated_name = paginated_name.replace('.html', '%s.html' % (page_num+1)) + + _write_file(template, paginated_localcontext, self.output_path, paginated_name) + else: + # no pagination + _write_file(template, localcontext, self.output_path, name) def update_context_contents(self, name, context): """Recursively run the context to find elements (articles, pages, etc) whose content getter needs to