= Template Plugins = [[TOC]] == 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 nothing - {{{setup()}}} 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 calling {{{PluginLoader.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) }}} ---- DeveloperGuidelines DeveloperGuidelines DeveloperGuidelines