Template Plugins
Table of Contents
Introduction
Plugins for templates are Python modules (or packages) which are hooked into the request cycle and can thus extend the current template configuration.
Those modules can be developed independently of Sahana, and are installed by simply placing them into the modules/plugins folder.
Installation
- tbw
Implementation
A template plugin can be a Python module or a Python package. The name of the module/package becomes the plugin name.
It must expose a function setup()
:
setup()
takes no arguments, and returns nothingsetup()
will be called during every request cycle (so minimize the load!)setup()
will be called immediately before the controller is executed
# Example plugin __version__ = "0.0.0" def setup(): # The plugin can access and alter deployment settings settings = current.deployment_settings
The plugin module/package can additionally define a __version__
string, which becomes accessible via current.session:
# The session holds the registry of current plugins registry = current.session.s3.plugins # The registry is a dict of tuples {plugin_name: (version, status)} plugin_info = registry.get(plugin_name) # - version is the __version__ string defined by the plugin or "unknown" # - status is True if the plugin's setup function was successful, otherwise False if plugin_info: version, status = plugin_info else: # Plugin has not been loaded yet version, status = None, None
Notes:
- plugins should raise an exception in case of unrecoverable errors during setup, in order to deactivate themselves
- plugins are responsible to log all their errors themselves, using
current.log
- a plugin's
setup()
must not redirect or otherwise raise HTTP30x (that would give an indefinite redirection loop) - there is no particular order in which plugins are run - plugins with conflicts should auto-detect each other (via registry), log the problem, and then raise an exception during setup in order to deactivate themselves
- a plugin with
status=False
will not automatically be reloaded. Reloading can be enforced by restarting the server thread, by callingPluginLoader.load(plugin_name, force=True)
, or by setting the registry entry to None:
# Enforce immediate reload of a plugin from plugins import PluginLoader PluginLoader.load(plugin_name, force=True) # Setting the registry entry to None triggers a reload in the next request cycle registry = current.session.s3.plugins registry[plugin_name] = None
It is also possible to reload all plugins:
# Re-run plugin detection and run all setups: from plugins import PluginLoader PluginLoader.setup_all(reload_all=True) # Re-run plugin detection, but without running setups: from plugins import PluginLoader PluginLoader.detect(reset_all=True)