diff piecrust/plugins/base.py @ 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 bf9f4e55f751
children 8f8bbb2e70e1
line wrap: on
line diff
--- 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