| 16 | | * ''tbw'' |
| | 16 | A ''template plugin'' can be a Python module or a Python package. The name of the module/package becomes the plugin name. |
| | 17 | |
| | 18 | It must expose a function {{{setup()}}}: |
| | 19 | - {{{setup()}}} takes no arguments, and returns nothing |
| | 20 | - {{{setup()}}} will be called during ''every'' request cycle (so minimize the load!) |
| | 21 | - {{{setup()}}} will be called immediately before the controller is executed |
| | 22 | |
| | 23 | {{{ |
| | 24 | # Example plugin |
| | 25 | |
| | 26 | __version__ = "0.0.0" |
| | 27 | |
| | 28 | def setup(): |
| | 29 | |
| | 30 | # The plugin can access and alter deployment settings |
| | 31 | settings = current.deployment_settings |
| | 32 | }}} |
| | 33 | |
| | 34 | The plugin module/package can additionally define a {{{__version__}}} string, which becomes accessible via current.session: |
| | 35 | |
| | 36 | {{{ |
| | 37 | # The session holds the registry of current plugins |
| | 38 | registry = current.session.s3.plugins |
| | 39 | |
| | 40 | # The registry is a dict of tuples {plugin_name: (version, status)} |
| | 41 | plugin_info = registry.get(plugin_name) |
| | 42 | |
| | 43 | # - version is the __version__ string defined by the plugin or "unknown" |
| | 44 | # - status is True if the plugin's setup function was successful, otherwise False |
| | 45 | if plugin_info: |
| | 46 | version, status = plugin_info |
| | 47 | else: |
| | 48 | # Plugin has not been loaded yet |
| | 49 | version, status = None, None |
| | 50 | }}} |
| | 51 | |
| | 52 | '''Notes:''' |
| | 53 | |
| | 54 | - plugins '''should''' raise an exception in case of unrecoverable errors during setup, in order to deactivate themselves |
| | 55 | - plugins are responsible to log all their errors themselves, using {{{current.log}}} |
| | 56 | - plugins '''must not''' redirect (HTTP 30x) unconditionally (that would give an indefinite redirection loop) |
| | 57 | - 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 |
| | 58 | - 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: |
| | 59 | |
| | 60 | {{{ |
| | 61 | # Enforce immediate reload of a plugin |
| | 62 | from plugins import PluginLoader |
| | 63 | PluginLoader.load(plugin_name, force=True) |
| | 64 | |
| | 65 | # Setting the registry entry to None triggers a reload in the next request cycle |
| | 66 | registry = current.session.s3.plugins |
| | 67 | registry[plugin_name] = None |
| | 68 | }}} |
| | 69 | |
| | 70 | It is also possible to reload all plugins: |
| | 71 | |
| | 72 | {{{ |
| | 73 | # Re-run plugin detection and run all setups: |
| | 74 | from plugins import PluginLoader |
| | 75 | PluginLoader.setup_all(reload_all=True) |
| | 76 | |
| | 77 | # Re-run plugin detection, but without running setups: |
| | 78 | from plugins import PluginLoader |
| | 79 | PluginLoader.detect(reset_all=True) |
| | 80 | }}} |