diff --git a/pelican/__init__.py b/pelican/__init__.py index 12d12210..cf99295e 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -1,5 +1,8 @@ import argparse import os +import pkgutil + +from blinker import signal from pelican.generators import (ArticlesGenerator, PagesGenerator, StaticGenerator, PdfGenerator) @@ -13,7 +16,7 @@ VERSION = "2.6.0" class Pelican(object): def __init__(self, settings=None, path=None, theme=None, output_path=None, - markup=None, keep=False): + markup=None, keep=False, plugins_path=None): """Read the settings, and performs some checks on the environment before doing anything else. """ @@ -41,6 +44,15 @@ class Pelican(object): self.theme = theme_path else: raise Exception("Impossible to find the theme %s" % theme) + + plugins_path = plugins_path or settings['PLUGINS_PATH'] + if plugins_path: + plugins_path = os.path.abspath(plugins_path) + self.load_plugins(plugins_path) + else: + self.plugins = None + + signal('pelican_initialized').send(self) def run(self): """Run the generators and return""" @@ -81,6 +93,13 @@ class Pelican(object): def get_writer(self): return Writer(self.output_path, settings=self.settings) + + def load_plugins(self,path): + loaded = [] + for module_loader, name, ispkg in pkgutil.walk_packages(path=[path,]): + loaded.append( module_loader.find_module(name).load_module(name) ) + self.plugins = loaded + @@ -116,6 +135,8 @@ def main(): parser.add_argument('-r', '--autoreload', dest='autoreload', action='store_true', help="Relaunch pelican each time a modification occurs on the content" "files") + parser.add_argument('-p', '--plugins', default=None, dest='plugins_path', + help='the path of plugins to use') args = parser.parse_args() log.init(args.verbosity) @@ -134,7 +155,7 @@ def main(): cls = getattr(module, cls_name) try: - pelican = cls(settings, args.path, args.theme, args.output, markup, args.keep) + pelican = cls(settings, args.path, args.theme, args.output, markup, args.keep, args.plugins_path) if args.autoreload: while True: try: diff --git a/pelican/generators.py b/pelican/generators.py index 569d5f50..38826a49 100755 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -8,6 +8,8 @@ import os import math import random +from blinker import signal + from jinja2 import Environment, FileSystemLoader from jinja2.exceptions import TemplateNotFound @@ -92,6 +94,7 @@ class ArticlesGenerator(Generator): self.dates = {} self.tags = defaultdict(list) self.categories = defaultdict(list) + self.signal = {'pelican_article_generate_context' : signal('pelican_article_generate_context')} super(ArticlesGenerator, self).__init__(*args, **kwargs) def generate_feeds(self, writer): @@ -200,6 +203,8 @@ class ArticlesGenerator(Generator): and self.settings['FALLBACK_ON_FS_DATE']: metadatas['date'] = datetime.fromtimestamp(os.stat(f).st_ctime) + self.signal['pelican_article_generate_context'].send(self, metadatas=metadatas) + article = Article(content, metadatas, settings=self.settings, filename=f) if not is_valid_content(article, f): diff --git a/pelican/readers.py b/pelican/readers.py index 4e1d7b2e..6d0b6cea 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -49,9 +49,14 @@ class RstReader(Reader): rendered_content = core.publish_parts(text, writer_name='html', settings_overrides=extra_params) title = rendered_content.get('title') + subtitle = rendered_content.get('subtitle') or '' content = rendered_content.get('body') + if not metadatas.has_key('title'): metadatas['title'] = title + if not metadatas.has_key('subtitle'): + metadatas['subtitle'] = subtitle + return content, metadatas class MarkdownReader(Reader): diff --git a/pelican/settings.py b/pelican/settings.py index 6c0918a0..3786b7f5 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -37,6 +37,7 @@ _DEFAULT_CONFIG = {'PATH': None, 'WITH_PAGINATION': False, 'DEFAULT_PAGINATION': 5, 'DEFAULT_ORPHANS': 0, + 'PLUGINS_PATH': None, } def read_settings(filename): diff --git a/plugins_samples/global_license.py b/plugins_samples/global_license.py new file mode 100644 index 00000000..eeb20965 --- /dev/null +++ b/plugins_samples/global_license.py @@ -0,0 +1,23 @@ +from blinker import signal + +""" +License plugin for Pelican +========================== + +Simply add license variable in article's context, which contain +the license text. + +Settings: +--------- + +Add LICENSE to your settings file to define default license. + +""" + +def add_license(generator, metadatas): + if 'license' not in metadatas.keys()\ + and 'LICENSE' in generator.settings.keys(): + metadatas['license'] = generator.settings['LICENSE'] + + +signal('pelican_article_generate_context').connect(add_license) diff --git a/plugins_samples/gravatar.py b/plugins_samples/gravatar.py new file mode 100644 index 00000000..9887e97e --- /dev/null +++ b/plugins_samples/gravatar.py @@ -0,0 +1,39 @@ +import hashlib + +from blinker import signal +""" +Gravata plugin for Pelican +========================== + +Simply add author_gravatar variable in article's context, which contain +the gravatar url. + +Settings: +--------- + +Add AUTHOR_EMAIL to your settings file to define default author email + +Article metadatas: +------------------ + +:email: article's author email + +If one of them are defined the author_gravatar variable is added to +article's context. +""" + +def add_gravatar(generator, metadatas): + + #first check email + if 'email' not in metadatas.keys()\ + and 'AUTHOR_EMAIL' in generator.settings.keys(): + metadatas['email'] = generator.settings['AUTHOR_EMAIL'] + + #then add gravatar url + if 'email' in metadatas.keys(): + gravatar_url = "http://www.gravatar.com/avatar/" + \ + hashlib.md5(metadatas['email'].lower()).hexdigest() + metadatas["author_gravatar"] = gravatar_url + + +signal('pelican_article_generate_context').connect(add_gravatar) diff --git a/plugins_samples/initialized.py b/plugins_samples/initialized.py new file mode 100644 index 00000000..f104c275 --- /dev/null +++ b/plugins_samples/initialized.py @@ -0,0 +1,7 @@ +from blinker import signal + + +def test(sender): + print "%s initialized !!" % sender + +signal('pelican_initialized').connect(test) diff --git a/setup.py b/setup.py index 936a3171..4744d0fb 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import sys VERSION = "2.6.0" # find a better way to do so. -requires = ['feedgenerator', 'jinja2', 'pygments', 'docutils', 'Markdown'] +requires = ['feedgenerator', 'jinja2', 'pygments', 'docutils', 'Markdown', 'blinker'] if sys.version_info < (2,7): requires.append('argparse')