G'day,

With those two asides, I would guess that we all have come across the problem of writing a fully-featured plugin architecture.

Trac plugin architecture is a nice starting point, as you describe. I have no idea about JEdit plugins, but I did have a good look at Eclipse plugins before writing the current (3rd) version of the PIDA plugin architecture.

PIDA has two levels of "plugin". The first is a very low-level thing, akin to the Trac architecture but more featured. The second level is the level at which this architecture is used to create actual plugins that do real things.

The low level plugin is essentially a registry where other components can register things. The three kind of things that a component can register with the registry are "Singletons", "Features", and "Extension Points". I won't bore you with the details, you can check the docstring at http://pida.co.uk/trac/browser/trunk/pida/core/plugins.py.

Those who have been on this list for a while might remember the Envisage
project being mentioned - well it is still alive! Envisage is at its core
*just* a plugin system based initially on the concepts of Eclipse, and for the
latest version, hopefully made more 'pythonic'... It should be pointed out that
Envisage is built using traits which allows optional static-typing/interfaces
etc... Traits and Envisage are both open source (BSD-style license) and can be
found at http://code.enthought.com...

Here is a (really) quick overview of Envisage's new plugin/extension 
mechanism...

a) To create a plugin
---------------------

1) Subclass enthought.envisage.api.Plugin

e.g::

class MyPlugin(Plugin):
    id = 'myplugin'
    name = 'My Plugin'
    ...

2) Assuming you are using the egg-based plugin manager (the default), add the
following line to your egg::

[enthought.envisage.plugins]
my_plugin = mypackage.api:MyPlugin

b) To declare that my plugin offers an extension point
------------------------------------------------------

class MyPlugin(Plugin):
   ...
   foos = ExtensionPoint(List(IFoo), id='myplugin.foos')

Key points:-

- extension point has Id and shows type of contributions expected
- to access any contributions to the extension point in the plugin just use
'self.foos'...

c) To contribute to an extension point
--------------------------------------

class SomeOtherPlugin(Plugin):
    id = 'someotherplugin'

    @extension_point('myplugin.foos')
    def get_foos(self, application):
        """ Return my contributions to the foos. """

    return [Foo1(), Foo2(), Foo3()]

And that's it! I think we now have a pretty simple, but powerful plugin and
extension mechanism, and Envisage applications are simply built from a
collection of plugins (by default we use Python Eggs to find them, but that it
not a requirement)...

Just thought I'd post an update...

Martin


Reply via email to