Fix #1647: Fix ARTICLE_ORDER_BY and add the ability to reverse order

ARTICLE_ORDER_BY wasn't doing anything because the ArticlesGenerator
was sorting articles after ARTICLE_ORDER_BY was applied. This fixes
that by adding the ability to reverse metadata order by adding the
option prefix 'reversed-' to metadata and changing the default value
to 'reversed-date'.

Relevant documentation is also updated and moved into a more appropriate
place ('Ordering Content' instead of 'URL settings').
This commit is contained in:
Deniz Turgut 2015-06-12 17:15:19 -04:00
commit da8b469ab8
5 changed files with 115 additions and 35 deletions

View file

@ -561,8 +561,7 @@ class ArticlesGenerator(CachingGenerator):
self.tags[tag].append(article)
for author in getattr(article, 'authors', []):
self.authors[author].append(article)
# sort the articles by date
self.articles.sort(key=attrgetter('date'), reverse=True)
self.dates = list(self.articles)
self.dates.sort(key=attrgetter('date'),
reverse=self.context['NEWEST_FIRST_ARCHIVES'])

View file

@ -65,7 +65,7 @@ DEFAULT_CONFIG = {
'OUTPUT_RETENTION': [],
'ARTICLE_URL': '{slug}.html',
'ARTICLE_SAVE_AS': '{slug}.html',
'ARTICLE_ORDER_BY': 'slug',
'ARTICLE_ORDER_BY': 'reversed-date',
'ARTICLE_LANG_URL': '{slug}-{lang}.html',
'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',
'DRAFT_URL': 'drafts/{slug}.html',

View file

@ -387,6 +387,65 @@ class TestArticlesGenerator(unittest.TestCase):
'パイソン', 'マック'])
self.assertEqual(tags, tags_expected)
def test_article_order_by(self):
settings = get_settings(filenames={})
settings['DEFAULT_CATEGORY'] = 'Default'
settings['DEFAULT_DATE'] = (1970, 1, 1)
settings['CACHE_CONTENT'] = False # cache not needed for this logic tests
settings['ARTICLE_ORDER_BY'] = 'title'
generator = ArticlesGenerator(
context=settings.copy(), settings=settings,
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
generator.generate_context()
expected = [
'An Article With Code Block To Test Typogrify Ignore',
'Article title',
'Article with Nonconformant HTML meta tags',
'Article with markdown and summary metadata multi',
'Article with markdown and summary metadata single',
'Article with markdown containing footnotes',
'Article with template',
'Rst with filename metadata',
'Test Markdown extensions',
'Test markdown File',
'Test md File',
'Test mdown File',
'Test mkd File',
'This is a super article !',
'This is a super article !',
'This is a super article !',
'This is a super article !',
'This is a super article !',
'This is a super article !',
'This is an article with category !',
'This is an article with multiple authors in lastname, firstname format!',
'This is an article with multiple authors in list format!',
'This is an article with multiple authors!',
'This is an article with multiple authors!',
'This is an article without category !',
'This is an article without category !',
'マックOS X 10.8でパイソンとVirtualenvをインストールと設定']
articles = [article.title for article in generator.articles]
self.assertEqual(articles, expected)
# reversed title
settings = get_settings(filenames={})
settings['DEFAULT_CATEGORY'] = 'Default'
settings['DEFAULT_DATE'] = (1970, 1, 1)
settings['CACHE_CONTENT'] = False # cache not needed for this logic tests
settings['ARTICLE_ORDER_BY'] = 'reversed-title'
generator = ArticlesGenerator(
context=settings.copy(), settings=settings,
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
generator.generate_context()
articles = [article.title for article in generator.articles]
self.assertEqual(articles, list(reversed(expected)))
class TestPageGenerator(unittest.TestCase):
# Note: Every time you want to test for a new field; Make sure the test
@ -473,6 +532,23 @@ class TestPageGenerator(unittest.TestCase):
pages = self.distill_pages(generator.pages)
self.assertEqual(pages_expected_sorted_by_title, pages)
# sort by title reversed
pages_expected_sorted_by_title = [
['This is a test page with a preset template', 'published',
'custom'],
['This is a test page', 'published', 'page'],
['This is a markdown test page', 'published', 'page'],
['Page with a bunch of links', 'published', 'page'],
['A Page (Test) for sorting', 'published', 'page'],
]
settings['PAGE_ORDER_BY'] = 'reversed-title'
generator = PagesGenerator(
context=settings.copy(), settings=settings,
path=CUR_DIR, theme=settings['THEME'], output_path=None)
generator.generate_context()
pages = self.distill_pages(generator.pages)
self.assertEqual(pages_expected_sorted_by_title, pages)
def test_tag_and_category_links_on_generated_pages(self):
"""
Test to ensure links of the form {tag}tagname and {category}catname

View file

@ -541,16 +541,28 @@ def process_translations(content_list, order_by=None):
try:
index.sort(key=order_by)
except Exception:
logger.error('Error sorting with function {}'.format(order_by))
elif order_by == 'basename':
index.sort(key=lambda x: os.path.basename(x.source_path or ''))
elif order_by != 'slug':
try:
index.sort(key=attrgetter(order_by))
except AttributeError:
error_msg = ('There is no "{}" attribute in the item metadata.'
'Defaulting to slug order.')
logger.warning(error_msg.format(order_by))
logger.error('Error sorting with function %s', order_by)
elif isinstance(order_by, six.string_types):
if order_by.startswith('reversed-'):
order_reversed = True
order_by = order_by.replace('reversed-', '', 1)
else:
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):
try:
index.sort(key=attrgetter(order_by),
reverse=order_reversed)
except AttributeError:
logger.warning('There is no "%s" attribute in the item '
'metadata. Defaulting to slug order.', order_by)
else:
logger.warning('Invalid *_ORDER_BY setting (%s).'
'Valid options are strings and functions.', order_by)
return index, translations