|
@@ -0,0 +1,93 @@
|
|
|
+# -*- 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)
|