12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- # -*- coding: utf-8 -*-
- """
- @Author: Alistair Magee
- Adds support for subcategories on pelican articles
- """
- import os
- from collections import defaultdict
- from pelican import signals
- from pelican.urlwrappers import URLWrapper, Category
- from operator import attrgetter
- from functools import partial
- from six import text_type
- class SubCategory(URLWrapper):
- def __init__(self, name, parent, *args, **kwargs):
- super(SubCategory, self).__init__(name, *args, **kwargs)
- self.parent = parent
- if isinstance(self.parent, SubCategory):
- self.savepath = os.path.join(self.parent.savepath, self.slug)
- self.fullurl = '{}/{}'.format(self.parent.fullurl, self.slug)
- else: #parent is a category
- self.savepath = os.path.join(self.parent.slug, self.slug)
- self.fullurl = '{}/{}'.format(self.parent.slug, self.slug)
- def as_dict(self):
- d = self.__dict__
- d['name'] = self.name
- d['savepath'] = self.savepath
- d['fullurl'] = self.fullurl
- d['parent'] = self.parent
- return d
- def get_subcategories(generator, metadata):
- if 'SUBCATEGORY_SAVE_AS' not in generator.settings:
- generator.settings['SUBCATEGORY_SAVE_AS'] = os.path.join(
- 'subcategory', '{savepath}.html')
- if 'SUBCATEGORY_URL' not in generator.settings:
- generator.settings['SUBCATEGORY_URL'] = 'subcategory/{fullurl}.html'
- category_list = text_type(metadata.get('category')).split('/')
- category = (category_list.pop(0)).strip()
- category = Category(category, generator.settings)
- metadata['category'] = category
- #generate a list of subcategories with their parents
- sub_list = []
- parent = category
- for subcategory in category_list:
- subcategory.strip()
- subcategory = SubCategory(subcategory, parent, generator.settings)
- sub_list.append(subcategory)
- parent = subcategory
- metadata['subcategories'] = sub_list
- def organize_subcategories(generator):
- generator.subcategories = defaultdict(list)
- for article in generator.articles:
- subcategories = article.metadata.get('subcategories')
- for cat in subcategories:
- generator.subcategories[cat].append(article)
- def generate_subcategories(generator, writer):
- write = partial(writer.write_file,
- relative_urls=generator.settings['RELATIVE_URLS'])
- subcategory_template = generator.get_template('subcategory')
- for subcat, articles in generator.subcategories.items():
- articles.sort(key=attrgetter('date'), reverse=True)
- dates = [article for article in generator.dates if article in articles]
- write(subcat.save_as, subcategory_template, generator.context,
- subcategory=subcat, articles=articles, dates=dates,
- paginated={'articles': articles, 'dates': dates},
- page_name=subcat.page_name, all_articles=generator.articles)
- def generate_subcategory_feeds(generator, writer):
- for subcat, articles in generator.subcategories.items():
- articles.sort(key=attrgetter('date'), reverse=True)
- if generator.settings.get('SUBCATEGORY_FEED_ATOM'):
- writer.write_feed(articles, generator.context,
- generator.settings['SUBCATEGORY_FEED_ATOM']
- % subcat.fullurl)
- if generator.settings.get('SUBCATEGORY_FEED_RSS'):
- writer.write_feed(articles, generator.context,
- generator.settings['SUBCATEGORY_FEED_RSS']
- % subcat.fullurl, feed_type='rss')
- def generate(generator, writer):
- generate_subcategory_feeds(generator, writer)
- generate_subcategories(generator, writer)
- def register():
- signals.article_generator_context.connect(get_subcategories)
- signals.article_generator_finalized.connect(organize_subcategories)
- signals.article_writer_finalized.connect(generate)
|