Sfoglia il codice sorgente

A plugin to add subcategories to Article categories

Alistair Magee 10 anni fa
parent
commit
48b990c0cd
3 ha cambiato i file con 129 aggiunte e 0 eliminazioni
  1. 51 0
      subcategory/README.md
  2. 1 0
      subcategory/__init__.py
  3. 77 0
      subcategory/subcategory.py

+ 51 - 0
subcategory/README.md

@@ -0,0 +1,51 @@
+#Subcategory Plugin#
+
+Adds support for subcategories in addition to article categories.
+
+Subcategories are heirachial. Each subcategory has a parent, which is either a
+regular category or another subcategory. Subcategories with the same name but 
+different parents are not the same. Their articles won't be grouped together 
+under that name.
+
+##Usage##
+
+Subcategories are an extension to categories. Add subcategories to an article's
+category metadata using a `/` like this:
+
+    Category: Regular Category/Sub-Category/Sub-Sub-category
+
+then create a `subcategory.html` template in your theme similar to the 
+`category.html` or `tag.html`
+
+In your templates `article.category` continues to act the same way. Your 
+subcategories are stored in a list `aricles.subcategories`. To create a 
+breadcrumb style navigation you might try something like this:
+
+    <nav class="breadcrumb">
+    <ol>
+        <li>
+            <a href="{{ SITEURL }}/{{ arcticle.categor.url }}">{{ article.category}}</a>
+        </li>
+    {% for subcategory in article.subcategories %}
+        <li>
+            <a href="{{ SITEURL }}/{{ category.url }}>{{ subcategory }}</a>
+        </li>
+    {% endfor %}
+    </ol>
+    </nav>
+ 
+
+##Settings##
+
+Consistent with the default settings for Tags and Categories, the default 
+settings for subcategoris are:
+    
+    'SUBCATEGORY_SAVE_AS' = os.path.join('subcategory', '{savepath}.html')
+    'SUBCATEGORY_URL' = 'subcategory/(fullurl).html'
+
+`savepath` and `fullurl` are generated recursively, using slugs. So the full
+url would be:
+    
+    category-slug/sub-category-slug/sub-sub-category-slug
+
+with `savepath` being similar but joined using `os.path.join`

+ 1 - 0
subcategory/__init__.py

@@ -0,0 +1 @@
+from .subcategory import *

+ 77 - 0
subcategory/subcategory.py

@@ -0,0 +1,77 @@
+# -*- 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 sub_cat, articles in generator.subcategories.items():
+        articles.sort(key=attrgetter('date'), reverse=True)
+        dates = [article for article in generator.dates if article in articles]
+        write(sub_cat.save_as, subcategory_template, generator.context, 
+                subcategory=sub_cat, articles=articles, dates=dates, 
+                paginated={'articles': articles, 'dates': dates},
+                page_name=sub_cat.page_name, all_articles=generator.articles)
+
+def register():
+    signals.article_generator_context.connect(get_subcategories)
+    signals.article_generator_finalized.connect(organize_subcategories)
+    signals.article_writer_finalized.connect(generate_subcategories)