Plugin manager

The PluginManager is a class defined in gluon.tools. Before we explain how it works inside, we will explain how to use it.

Here we consider the previous plugin_comments and we make it better. We want to be able to customize:

  1. db.plugin_comments_comment.body.label

without having to edit the plugin code itself.

Here is how we can do it:

First, rewrite the plugin “models/plugin_comments.py” in this way:

  1. def _():
  2. from gluon.tools import PluginManager
  3. plugins = PluginManager('comments', body_label='Your comment')
  4. db.define_table('plugin_comments_comment',
  5. Field('body', 'text', label=plugins.comments.body_label),
  6. auth.signature)
  7. return lambda: LOAD('plugin_comments', 'post.load', ajax=True)
  8. plugin_comments = _()

Notice how all the code except the table definition is encapsulated in a single function called _ so that it does not pollute the global namespace. Also notice how the function creates an instance of a PluginManager.

Now in any other model in your app, for example in “models/db.py”, you can configure this plugin as follows:

  1. from gluon.tools import PluginManager
  2. plugins = PluginManager()
  3. plugins.comments.body_label = T('Post a comment')

The plugins object is already instantiated in the default scaffolding app in “models/db.py”

The PluginManager object is a thread-level singleton Storage object of Storage objects. That means you can instantiate as many as you like within the same application but (whether they have the same name or not) they act as if there were a single PluginManager instance.

In particular each plugin file can make its own PluginManager object and register itself and its default parameters with it:

  1. plugins = PluginManager('name', param1='value', param2='value')

You can override these parameters elsewhere (for example in “models/db.py”) with the code:

  1. plugins = PluginManager()
  2. plugins.name.param1 = 'other value'

You can configure multiple plugins in one place.

  1. plugins = PluginManager()
  2. plugins.name.param1 = '...'
  3. plugins.name.param2 = '...'
  4. plugins.name1.param3 = '...'
  5. plugins.name2.param4 = '...'
  6. plugins.name3.param5 = '...'

When the plugin is defined, the PluginManager must take arguments: the plugin name and optional named arguments which are default parameters. However, when the plugins are configured, the PluginManager constructor must take no arguments. The configuration must precede the definition of the plugin (i.e. it must be in a model file that comes first alphabetically).