Merge pull request #2292 from oulenz/article_order

Remove hardcoded sorting of articles within categories, tags, authors, feeds
This commit is contained in:
Justin Mayer 2018-04-06 12:08:29 -07:00 committed by GitHub
commit 5ca1cabe78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 32 deletions

View file

@ -21,8 +21,9 @@ from pelican import signals
from pelican.cache import FileStampDataCacher from pelican.cache import FileStampDataCacher
from pelican.contents import Article, Page, Static from pelican.contents import Article, Page, Static
from pelican.readers import Readers from pelican.readers import Readers
from pelican.utils import (DateFormatter, copy, mkdir_p, posixize_path, from pelican.utils import (DateFormatter, copy, mkdir_p, order_content,
process_translations, python_2_unicode_compatible) posixize_path, process_translations,
python_2_unicode_compatible)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -310,7 +311,8 @@ class ArticlesGenerator(CachingGenerator):
all_articles = list(self.articles) all_articles = list(self.articles)
for article in self.articles: for article in self.articles:
all_articles.extend(article.translations) 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'): if self.settings.get('FEED_ALL_ATOM'):
writer.write_feed(all_articles, self.context, writer.write_feed(all_articles, self.context,
@ -328,7 +330,6 @@ class ArticlesGenerator(CachingGenerator):
feed_type='rss') feed_type='rss')
for cat, arts in self.categories: for cat, arts in self.categories:
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('CATEGORY_FEED_ATOM'): if self.settings.get('CATEGORY_FEED_ATOM'):
writer.write_feed(arts, self.context, writer.write_feed(arts, self.context,
self.settings['CATEGORY_FEED_ATOM'] self.settings['CATEGORY_FEED_ATOM']
@ -349,7 +350,6 @@ class ArticlesGenerator(CachingGenerator):
feed_type='rss') feed_type='rss')
for auth, arts in self.authors: for auth, arts in self.authors:
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('AUTHOR_FEED_ATOM'): if self.settings.get('AUTHOR_FEED_ATOM'):
writer.write_feed(arts, self.context, writer.write_feed(arts, self.context,
self.settings['AUTHOR_FEED_ATOM'] self.settings['AUTHOR_FEED_ATOM']
@ -372,7 +372,6 @@ class ArticlesGenerator(CachingGenerator):
if (self.settings.get('TAG_FEED_ATOM') or if (self.settings.get('TAG_FEED_ATOM') or
self.settings.get('TAG_FEED_RSS')): self.settings.get('TAG_FEED_RSS')):
for tag, arts in self.tags.items(): for tag, arts in self.tags.items():
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('TAG_FEED_ATOM'): if self.settings.get('TAG_FEED_ATOM'):
writer.write_feed(arts, self.context, writer.write_feed(arts, self.context,
self.settings['TAG_FEED_ATOM'] self.settings['TAG_FEED_ATOM']
@ -398,7 +397,8 @@ class ArticlesGenerator(CachingGenerator):
translations_feeds[article.lang].append(article) translations_feeds[article.lang].append(article)
for lang, items in translations_feeds.items(): 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'): if self.settings.get('TRANSLATION_FEED_ATOM'):
writer.write_feed( writer.write_feed(
items, self.context, items, self.context,
@ -510,7 +510,6 @@ class ArticlesGenerator(CachingGenerator):
"""Generate Tags pages.""" """Generate Tags pages."""
tag_template = self.get_template('tag') tag_template = self.get_template('tag')
for tag, articles in self.tags.items(): 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] dates = [article for article in self.dates if article in articles]
write(tag.save_as, tag_template, self.context, tag=tag, write(tag.save_as, tag_template, self.context, tag=tag,
url=tag.url, articles=articles, dates=dates, url=tag.url, articles=articles, dates=dates,
@ -521,7 +520,6 @@ class ArticlesGenerator(CachingGenerator):
"""Generate category pages.""" """Generate category pages."""
category_template = self.get_template('category') category_template = self.get_template('category')
for cat, articles in self.categories: for cat, articles in self.categories:
articles.sort(key=attrgetter('date'), reverse=True)
dates = [article for article in self.dates if article in articles] dates = [article for article in self.dates if article in articles]
write(cat.save_as, category_template, self.context, write(cat.save_as, category_template, self.context,
url=cat.url, category=cat, articles=articles, dates=dates, url=cat.url, category=cat, articles=articles, dates=dates,
@ -532,7 +530,6 @@ class ArticlesGenerator(CachingGenerator):
"""Generate Author pages.""" """Generate Author pages."""
author_template = self.get_template('author') author_template = self.get_template('author')
for aut, articles in self.authors: for aut, articles in self.authors:
articles.sort(key=attrgetter('date'), reverse=True)
dates = [article for article in self.dates if article in articles] dates = [article for article in self.dates if article in articles]
write(aut.save_as, author_template, self.context, write(aut.save_as, author_template, self.context,
url=aut.url, author=aut, articles=articles, dates=dates, url=aut.url, author=aut, articles=articles, dates=dates,
@ -601,8 +598,9 @@ class ArticlesGenerator(CachingGenerator):
all_drafts.append(article) all_drafts.append(article)
self.add_source_path(article) self.add_source_path(article)
self.articles, self.translations = process_translations( self.articles, self.translations = process_translations(all_articles)
all_articles, self.articles = order_content(
self.articles,
order_by=self.settings['ARTICLE_ORDER_BY']) order_by=self.settings['ARTICLE_ORDER_BY'])
self.drafts, self.drafts_translations = \ self.drafts, self.drafts_translations = \
process_translations(all_drafts) process_translations(all_drafts)
@ -698,9 +696,8 @@ class PagesGenerator(CachingGenerator):
hidden_pages.append(page) hidden_pages.append(page)
self.add_source_path(page) self.add_source_path(page)
self.pages, self.translations = process_translations( self.pages, self.translations = process_translations(all_pages)
all_pages, self.pages = order_content(self.pages, self.settings['PAGE_ORDER_BY'])
order_by=self.settings['PAGE_ORDER_BY'])
self.hidden_pages, self.hidden_translations = \ self.hidden_pages, self.hidden_translations = \
process_translations(hidden_pages) process_translations(hidden_pages)

View file

@ -613,7 +613,7 @@ def escape_html(text, quote=True):
return escape(text, quote=quote) return escape(text, quote=quote)
def process_translations(content_list, order_by=None): def process_translations(content_list):
""" Finds translation and returns them. """ Finds translation and returns them.
Returns a tuple with two lists (index, translations). Index list includes 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. the same slug have that metadata.
For each content_list item, sets the 'translations' attribute. 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')) content_list.sort(key=attrgetter('slug'))
grouped_by_slugs = groupby(content_list, 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: for a in items:
a.translations = [x for x in items if x != a] 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 order_by:
if callable(order_by): if callable(order_by):
try: try:
index.sort(key=order_by) content_list.sort(key=order_by)
except Exception: except Exception:
logger.error('Error sorting with function %s', order_by) logger.error('Error sorting with function %s', order_by)
elif isinstance(order_by, six.string_types): elif isinstance(order_by, six.string_types):
@ -705,13 +712,13 @@ def process_translations(content_list, order_by=None):
order_reversed = False order_reversed = False
if order_by == 'basename': if order_by == 'basename':
index.sort(key=lambda x: os.path.basename(x.source_path or ''), content_list.sort(
reverse=order_reversed) key=lambda x: os.path.basename(x.source_path or ''),
# already sorted by slug, no need to sort again reverse=order_reversed)
elif not (order_by == 'slug' and not order_reversed): else:
try: try:
index.sort(key=attrgetter(order_by), content_list.sort(key=attrgetter(order_by),
reverse=order_reversed) reverse=order_reversed)
except AttributeError: except AttributeError:
logger.warning( logger.warning(
'There is no "%s" attribute in the item ' '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).' 'Invalid *_ORDER_BY setting (%s).'
'Valid options are strings and functions.', order_by) 'Valid options are strings and functions.', order_by)
return index, translations return content_list
def folder_watcher(path, extensions, ignores=[]): def folder_watcher(path, extensions, ignores=[]):