Mercurial > piecrust2
changeset 848:7d83b9484b98
plugins: Add support for "ad-hoc" local plugins.
These are loose `.py` files inside of the `plugins` folder of a website.
They're loaded along with other normal (packaged) plugins.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 27 Apr 2017 20:54:29 -0700 |
parents | 71c4f43d8fc1 |
children | 8f8bbb2e70e1 |
files | piecrust/__init__.py piecrust/app.py piecrust/plugins/base.py |
diffstat | 3 files changed, 25 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/__init__.py Thu Apr 27 20:53:18 2017 -0700 +++ b/piecrust/__init__.py Thu Apr 27 20:54:29 2017 -0700 @@ -4,6 +4,7 @@ TEMPLATES_DIR = 'templates' THEME_DIR = 'theme' THEMES_DIR = 'themes' +PLUGINS_DIR = 'plugins' CONFIG_PATH = 'config.yml' THEME_CONFIG_PATH = 'theme_config.yml'
--- a/piecrust/app.py Thu Apr 27 20:53:18 2017 -0700 +++ b/piecrust/app.py Thu Apr 27 20:54:29 2017 -0700 @@ -7,7 +7,7 @@ from piecrust import ( RESOURCES_DIR, CACHE_DIR, TEMPLATES_DIR, ASSETS_DIR, - THEME_DIR, + THEME_DIR, PLUGINS_DIR, CONFIG_PATH, THEME_CONFIG_PATH) from piecrust.appconfig import PieCrustConfiguration from piecrust.cache import ExtensibleCache, NullExtensibleCache @@ -127,6 +127,10 @@ return os.path.join(RESOURCES_DIR, 'theme') @cached_property + def plugins_dir(self): + return self._get_dir(PLUGINS_DIR) + + @cached_property def cache_dir(self): return os.path.join(self.root_dir, CACHE_DIR, self.cache_key)
--- a/piecrust/plugins/base.py Thu Apr 27 20:53:18 2017 -0700 +++ b/piecrust/plugins/base.py Thu Apr 27 20:54:29 2017 -0700 @@ -1,5 +1,8 @@ +import os.path +import sys import logging import importlib +import importlib.util logger = logging.getLogger(__name__) @@ -113,9 +116,24 @@ plugin.initialize(self.app) def _loadPlugin(self, plugin_name): + mod_name = 'piecrust_%s' % plugin_name try: - mod = importlib.import_module('piecrust_' + plugin_name) + # Import from the current environment. + mod = importlib.import_module(mod_name) except ImportError as ex: + mod = None + + if mod is None: + # Import as a loose Python file from the plugins dir. + pfile = os.path.join(self.app.plugins_dir, plugin_name + '.py') + if os.path.isfile(pfile): + spec = importlib.util.spec_from_file_location(plugin_name, + pfile) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + sys.modules[mod_name] = mod + + if mod is None: logger.error("Failed to load plugin '%s'." % plugin_name) logger.error(ex) return