For my first few posts, I want to focus on some of the goals that we have for Raven. One of those goals is for the application to be as extensible as possible. For us, extensibility means easily adding new functionality to the application via the creation of plugins. In this post, I will talk a bit about our plugin system and what sorts of benefits we get from it.
Plugins/Extension Points
Our plugin system will be extremely familiar to anyone who has worked with the Eclipse Java IDE plugin system. A Zoundry Raven plugin consists, minimally, of a plugin descriptor file called zplugin.xml. The zplugin.xml file defines the ways in which the plugin will be extending the application. Here is a simple example:
<zoundry-plugin xmlns="http://www.zoundry.com/schemas/2006/03/zplugin.rng"
version="1.0"
name="Zoundry Common User Preferences"
id="zoundry.raven.appframework.prefs">
<dependencies>
<depends on="zoundry.raven.appframework.services" version="1.0"/>
</dependencies>
<!-- My Contributed Preference Page -->
<zoundry-extension point="zoundry.appframework.ui.preferences.prefpage">
<id>zoundry.appframework.ui.preferences.prefpage.myprefpage</id>
<class>foo.bar.ui.prefs.prefpages.MyFirstPreferencePage</class>
<extension-data>
<prefpage>
<parent/>
<name>My First Pref Page</name>
<description>This is an example preference page.</description>
<header-image>images/prefpages/foobar/header.png</header-image>
<icon>icons/prefpages/foobar.png</icon>
</prefpage>
</extension-data>
</zoundry-extension>
</zoundry-plugin>
The above sample zplugin.xml file defines a new Preference Page that would appear in the User Preferences dialog. In short, new functionality is contributed to the application via extension points declared within the zplugin.xml file found in each Zoundry Raven plugin. In the above example, the plugin is contributing a new User Preference page via the zoundry.appframework.ui.preferences.prefpage extension point. In this case, the plugin would also need to supply the actual implementation class called foo.bar.ui.prefs.prefpages.MyFirstPreferencePage by including some compiled python code as well, but the details of how that is done are beyond the scope of this post.
Extensions Without Python Coding
Now, not all extension points will require compiled python code. There are some extension points that are meaningful simply based on their zplugin.xml declaration. For instance, the application exposes the zoundry.blogapp.mediastore.site extension point, which allows a plugin to contribute a new place to upload media (e.g. images). The extension point would only need to include, for example, the default FTP information for a site. This would allow Zoundry Raven users to easily configure their account at the given site for media uploads. In other words, if a particular FTP-based image hosting company wanted to contribute a plugin that would cause their specific information to show up as a first-class option when a user configures a Media Store in Zoundry Raven, they can do so by simply contributing nothing but the zplugin.xml declaration XML.
Extensible Extensions
Finally, the plugin system (I really love this) is itself extensible! Zoundry Raven will ship with some set of extension points that plugins can contribute functionality to. At present, I would say we have about a dozen or so extension points. However, when a third party plugin contributes some functionality to the application, they may want their functionality to be extensible. This can be accomplished by contributing to the zoundry.extension extension point. The third party functionality can then access the Zoundry Raven plugin registry and query it for any extensions contributed to its extension point. In this way, other plugins can extend the functionality that was provided by the original third party plugin.
Extension Validation
Finally, it is worth noting that extension points will have a Relax NG schema associated with them when they are declared. This schema will be used to validate the XML found in the zplugin.xml file whenever a plugin contributes to an extension point. In this way, the application can be more confident that the extension was properly declared. In addition, for those extension points that require that a python class be specified, the schema will indicate what type (interface/base class) the contributed python class must be.
Ok, so now you know a little bit about how our plugin system works. In my next post, I will hopefully talk a little bit about the main application UI and provide a screen shot of how it looks at the moment (still in progress).
Labels: extensions, zoundry