75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
|
"""
|
||
|
collate_content.py
|
||
|
==================
|
||
|
(c) 2014 - Edward Stronge
|
||
|
|
||
|
Connects to the content generator finalized signal to combine
|
||
|
articles and pages sharing a category into lists that will be
|
||
|
available in the template context.
|
||
|
|
||
|
Thanks to #pelican member @kura for suggestions on creating this
|
||
|
plugin.
|
||
|
"""
|
||
|
from collections import defaultdict
|
||
|
import functools
|
||
|
import re
|
||
|
|
||
|
from pelican import signals
|
||
|
|
||
|
|
||
|
def group_content(generator, content_type):
|
||
|
"""
|
||
|
Assembles articles and pages into lists based on each
|
||
|
article or page's content. These lists are available
|
||
|
through the global context passed to the template engine.
|
||
|
|
||
|
When multiple categories are present, splits category names
|
||
|
based on commas and trims whitespace surrounding a
|
||
|
category's name. Thus, commas may not appear within a category
|
||
|
but they can be used to delimit categories and may be surrounded by
|
||
|
arbitrary amounts of whitespace.
|
||
|
|
||
|
For each category, substitutes '_' for all whitespace and '-'
|
||
|
characters, then creates a list named `SUBSTITUTED_CATEGORY_NAME`_articles
|
||
|
or `SUBSTITUTED_CATEGORY_NAME`_pages for Articles or Pages,
|
||
|
respectively.
|
||
|
|
||
|
Note that the *original* category name must appear in the
|
||
|
`CATEGORIES_TO_COLLATE` when using this plugin with category
|
||
|
filtering enabled.
|
||
|
"""
|
||
|
category_filter = generator.settings.get('CATEGORIES_TO_COLLATE', None)
|
||
|
filtering_active = type(category_filter) in (list, tuple, set)
|
||
|
|
||
|
collations = generator.context.get('collations', defaultdict(list))
|
||
|
for content in generator.context[content_type]:
|
||
|
category_list = [c.strip() for c in content.category.name.split(',')]
|
||
|
for category in category_list:
|
||
|
if filtering_active and category not in category_filter:
|
||
|
continue
|
||
|
category = substitute_category_name(category)
|
||
|
collations['%s_%s' % (category, content_type)].append(content)
|
||
|
generator.context['collations'] = collations
|
||
|
|
||
|
|
||
|
def substitute_category_name(category_name):
|
||
|
"""
|
||
|
Replaces whitespace and '-' characters in `category_name`
|
||
|
to allow category_name to be made into a valid Python
|
||
|
identifier.
|
||
|
|
||
|
Doesn't check all possible ways a string might be invalid;
|
||
|
the user of the collate_content module is advised to use
|
||
|
categories with Python-friendly names.
|
||
|
"""
|
||
|
return re.sub(r'\s', '_', category_name).replace('-', '_').lower()
|
||
|
|
||
|
ARTICLE_GROUPER = functools.partial(group_content, content_type='articles')
|
||
|
PAGE_GROUPER = functools.partial(group_content, content_type='pages')
|
||
|
|
||
|
|
||
|
def register():
|
||
|
"""Register the new plugin"""
|
||
|
signals.article_generator_finalized.connect(ARTICLE_GROUPER)
|
||
|
signals.page_generator_finalized.connect(PAGE_GROUPER)
|