123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- """
- 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)
|