From c160cb73cce7d002de1e869d4b660178f3b1974b Mon Sep 17 00:00:00 2001 From: Oliver Urs Lenz Date: Sun, 18 Mar 2018 12:21:56 +0100 Subject: [PATCH] remove hardcoded sorting of articles within categories, tags, authors, feeds --- pelican/generators.py | 27 ++++++++++++--------------- pelican/utils.py | 41 ++++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/pelican/generators.py b/pelican/generators.py index d93e740e..363d29cf 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -21,8 +21,9 @@ from pelican import signals from pelican.cache import FileStampDataCacher from pelican.contents import Article, Page, Static from pelican.readers import Readers -from pelican.utils import (DateFormatter, copy, mkdir_p, posixize_path, - process_translations, python_2_unicode_compatible) +from pelican.utils import (DateFormatter, copy, mkdir_p, order_content, + posixize_path, process_translations, + python_2_unicode_compatible) logger = logging.getLogger(__name__) @@ -300,7 +301,8 @@ class ArticlesGenerator(CachingGenerator): all_articles = list(self.articles) for article in self.articles: all_articles.extend(article.translations) - all_articles.sort(key=attrgetter('date'), reverse=True) + order_content(all_articles, + order_by=self.settings['ARTICLE_ORDER_BY']) if self.settings.get('FEED_ALL_ATOM'): writer.write_feed(all_articles, self.context, @@ -312,7 +314,6 @@ class ArticlesGenerator(CachingGenerator): feed_type='rss') for cat, arts in self.categories: - arts.sort(key=attrgetter('date'), reverse=True) if self.settings.get('CATEGORY_FEED_ATOM'): writer.write_feed(arts, self.context, self.settings['CATEGORY_FEED_ATOM'] @@ -325,7 +326,6 @@ class ArticlesGenerator(CachingGenerator): feed_type='rss') for auth, arts in self.authors: - arts.sort(key=attrgetter('date'), reverse=True) if self.settings.get('AUTHOR_FEED_ATOM'): writer.write_feed(arts, self.context, self.settings['AUTHOR_FEED_ATOM'] @@ -340,7 +340,6 @@ class ArticlesGenerator(CachingGenerator): if (self.settings.get('TAG_FEED_ATOM') or self.settings.get('TAG_FEED_RSS')): for tag, arts in self.tags.items(): - arts.sort(key=attrgetter('date'), reverse=True) if self.settings.get('TAG_FEED_ATOM'): writer.write_feed(arts, self.context, self.settings['TAG_FEED_ATOM'] @@ -358,7 +357,8 @@ class ArticlesGenerator(CachingGenerator): translations_feeds[article.lang].append(article) for lang, items in translations_feeds.items(): - items.sort(key=attrgetter('date'), reverse=True) + items = order_content( + items, order_by=self.settings['ARTICLE_ORDER_BY']) if self.settings.get('TRANSLATION_FEED_ATOM'): writer.write_feed( items, self.context, @@ -464,7 +464,6 @@ class ArticlesGenerator(CachingGenerator): """Generate Tags pages.""" tag_template = self.get_template('tag') for tag, articles in self.tags.items(): - articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(tag.save_as, tag_template, self.context, tag=tag, url=tag.url, articles=articles, dates=dates, @@ -475,7 +474,6 @@ class ArticlesGenerator(CachingGenerator): """Generate category pages.""" category_template = self.get_template('category') for cat, articles in self.categories: - articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(cat.save_as, category_template, self.context, url=cat.url, category=cat, articles=articles, dates=dates, @@ -486,7 +484,6 @@ class ArticlesGenerator(CachingGenerator): """Generate Author pages.""" author_template = self.get_template('author') for aut, articles in self.authors: - articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(aut.save_as, author_template, self.context, url=aut.url, author=aut, articles=articles, dates=dates, @@ -555,8 +552,9 @@ class ArticlesGenerator(CachingGenerator): all_drafts.append(article) self.add_source_path(article) - self.articles, self.translations = process_translations( - all_articles, + self.articles, self.translations = process_translations(all_articles) + self.articles = order_content( + self.articles, order_by=self.settings['ARTICLE_ORDER_BY']) self.drafts, self.drafts_translations = \ process_translations(all_drafts) @@ -652,9 +650,8 @@ class PagesGenerator(CachingGenerator): hidden_pages.append(page) self.add_source_path(page) - self.pages, self.translations = process_translations( - all_pages, - order_by=self.settings['PAGE_ORDER_BY']) + self.pages, self.translations = process_translations(all_pages) + self.pages = order_content(self.pages, self.settings['PAGE_ORDER_BY']) self.hidden_pages, self.hidden_translations = \ process_translations(hidden_pages) diff --git a/pelican/utils.py b/pelican/utils.py index ef9da23b..ab02801a 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -613,7 +613,7 @@ def escape_html(text, quote=True): return escape(text, quote=quote) -def process_translations(content_list, order_by=None): +def process_translations(content_list): """ Finds translation and returns them. Returns a tuple with two lists (index, translations). Index list includes @@ -623,14 +623,6 @@ def process_translations(content_list, order_by=None): the same slug have that metadata. For each content_list item, sets the 'translations' attribute. - - order_by can be a string of an attribute or sorting function. If order_by - is defined, content will be ordered by that attribute or sorting function. - By default, content is ordered by slug. - - Different content types can have default order_by attributes defined - in settings, e.g. PAGES_ORDER_BY='sort-order', in which case `sort-order` - should be a defined metadata attribute in each page. """ content_list.sort(key=attrgetter('slug')) grouped_by_slugs = groupby(content_list, attrgetter('slug')) @@ -691,10 +683,25 @@ def process_translations(content_list, order_by=None): for a in items: a.translations = [x for x in items if x != a] + return index, translations + + +def order_content(content_list, order_by='slug'): + """ Sorts content. + + order_by can be a string of an attribute or sorting function. If order_by + is defined, content will be ordered by that attribute or sorting function. + By default, content is ordered by slug. + + Different content types can have default order_by attributes defined + in settings, e.g. PAGES_ORDER_BY='sort-order', in which case `sort-order` + should be a defined metadata attribute in each page. + """ + if order_by: if callable(order_by): try: - index.sort(key=order_by) + content_list.sort(key=order_by) except Exception: logger.error('Error sorting with function %s', order_by) elif isinstance(order_by, six.string_types): @@ -705,13 +712,13 @@ def process_translations(content_list, order_by=None): order_reversed = False if order_by == 'basename': - index.sort(key=lambda x: os.path.basename(x.source_path or ''), - reverse=order_reversed) - # already sorted by slug, no need to sort again - elif not (order_by == 'slug' and not order_reversed): + content_list.sort( + key=lambda x: os.path.basename(x.source_path or ''), + reverse=order_reversed) + else: try: - index.sort(key=attrgetter(order_by), - reverse=order_reversed) + content_list.sort(key=attrgetter(order_by), + reverse=order_reversed) except AttributeError: logger.warning( 'There is no "%s" attribute in the item ' @@ -721,7 +728,7 @@ def process_translations(content_list, order_by=None): 'Invalid *_ORDER_BY setting (%s).' 'Valid options are strings and functions.', order_by) - return index, translations + return content_list def folder_watcher(path, extensions, ignores=[]):