Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ordering pages and articles when iterating in templates. #836

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ Setting name (default value) What does it do?
==================================================== =====================================================
`ARTICLE_URL` (``'{slug}.html'``) The URL to refer to an ARTICLE.
`ARTICLE_SAVE_AS` (``'{slug}.html'``) The place where we will save an article.
`ARTICLE_ORDER_BY` (``'slug'``) The metadata attribute used to sort articles. By default
the articles_page.object_list template variable is
ordered by slug. If you modify this, make sure all
articles contain the attribute you specify. You can
also specify a sorting function.
`ARTICLE_LANG_URL` (``'{slug}-{lang}.html'``) The URL to refer to an ARTICLE which doesn't use the
default language.
`ARTICLE_LANG_SAVE_AS` (``'{slug}-{lang}.html'``) The place where we will save an article which
Expand All @@ -227,6 +232,13 @@ Setting name (default value) What does it do?
`PAGE_SAVE_AS` (``'pages/{slug}.html'``) The location we will save the page. This value has to be
the same as PAGE_URL or you need to use a rewrite in
your server config.
`PAGE_ORDER_BY` (``'filename'``) The metadata attribute used to sort pages. By default
the PAGES template variable is ordered by filename
(path not included). Note that the option 'filename'
is a special option supported in the source code. If
you modify this settings, make sure all pages contain
the attribute you specify. You can also specify a
sorting function.
`PAGE_LANG_URL` (``'pages/{slug}-{lang}.html'``) The URL we will use to link to a page which doesn't
use the default language.
`PAGE_LANG_SAVE_AS` (``'pages/{slug}-{lang}.html'``) The location we will save the page which doesn't
Expand Down
6 changes: 4 additions & 2 deletions pelican/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ def generate_context(self):
(repr(article.status),
repr(f)))

self.articles, self.translations = process_translations(all_articles)
self.articles, self.translations = process_translations(all_articles,
order_by=self.settings['ARTICLE_ORDER_BY'])

for article in self.articles:
# only main articles are listed in categories and tags
Expand Down Expand Up @@ -529,7 +530,8 @@ def generate_context(self):
(repr(page.status),
repr(f)))

self.pages, self.translations = process_translations(all_pages)
self.pages, self.translations = process_translations(all_pages,
order_by=self.settings['PAGE_ORDER_BY'])
self.hidden_pages, self.hidden_translations = (
process_translations(hidden_pages))

Expand Down
2 changes: 2 additions & 0 deletions pelican/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@
'DELETE_OUTPUT_DIRECTORY': False,
'ARTICLE_URL': '{slug}.html',
'ARTICLE_SAVE_AS': '{slug}.html',
'ARTICLE_ORDER_BY': 'slug',
'ARTICLE_LANG_URL': '{slug}-{lang}.html',
'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',
'PAGE_URL': 'pages/{slug}.html',
'PAGE_SAVE_AS': os.path.join('pages', '{slug}.html'),
'PAGE_ORDER_BY': 'filename',
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
'PAGE_LANG_SAVE_AS': os.path.join(
'pages', '{slug}-{lang}.html'),
Expand Down
26 changes: 25 additions & 1 deletion pelican/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,14 +390,22 @@ def truncate_html_words(s, num, end_text='...'):
return out


def process_translations(content_list):
def process_translations(content_list, order_by=None):
""" Finds translation and returns them.

Returns a tuple with two lists (index, translations). Index list includes
items in default language or items which have no variant in default
language.

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'))
Expand Down Expand Up @@ -426,6 +434,22 @@ def process_translations(content_list):
translations.extend([x for x in items if x not in default_lang_items])
for a in items:
a.translations = [x for x in items if x != a]

if order_by:
if hasattr(order_by, '__call__'):
try:
index.sort(key=order_by)
except:
if hasattr(order_by, 'func_name'):
logger.error("Error sorting with function %s" % order_by.func_name)
else:
logger.error("Error sorting with function %r" % order_by)
elif order_by == 'filename':
index.sort(key=lambda x:os.path.basename(
x.source_path or ''))
elif order_by != 'slug':
index.sort(key=attrgetter(order_by))

return index, translations


Expand Down