This document describes the NewsBruiser plugin system, which makes it easy to add features to NewsBruiser.
When NewsBruiser starts up, it looks at all the directories under
nb/plugins/. If a directory has an
__init.py__ file, NewsBruiser runs the code in that
file. So the first step in creating a plugin is making a subdirectory
of nb/plugins/.
The plugins that come with NewsBruiser are sorted by what they
do. For instance, the plugins underneath entry/export
deal with notifying things external to NewsBruiser (such as files on
the filesystem, or other web sites) about changes to NewsBruiser
entries. Each plugin subdirectory has a description of the plugins
inside its README file; you can use the existing subdirectories to
guide your path, or make your own subdirectories.
You can define a new screen for your plugin by simply declaring a subclass of NBCGI and registering it with the NewsBruiser dispatch CGI.
To register your screen, put code like the following in your
plugin's __init__.py file (assuming your screens are all
kept in MyScreens.py):
from nb.NewsBruiserCGIs import DispatchCGI
import MyScreens
DispatchCGI.cgiModules.append(MyScreens.__name__)
You can put all your NBCGI subclasses in one module
(eg. MyScreens.py); DispatchCGI will scan that module for
NBCGI subclasses and register them all.
Make sure that your NBCGI subclass defines the NAME field, so that the dispatcher will know when a user is trying to access your screen. Every screen must have one and only one NAME, and no two screens can share a NAME.
Example: the api/XML-RPC plugin defines a new screen
that provides a CGI interface to XML-RPC.
Your plugin can be notified when certain important events happen in NewsBruiser, like an entry being published.
To have a method called when an event of type "Foo" happens, you
just define a function in __init__.py called eventFoo.
Right now there are four NewsBruiser events you can listen for:
Examples: The entry/export/ plugin listens for all
four events and propagates them to any registered EntryExporter
objects.
Entry filters can be used to automatically change the text of an entry. This is generally used to save some work on the part of the person who's typing in notebook entries by, eg. automatically linking URLs they type.
If you want to define an entry text filter, first define the transformation function. This function takes a NBCGI instance and a text string. It performs some transformation on the text and returns the transformed version.
Now you must register your filter. import the Entry
class and call Entry.registerFilter, passing in the type
of filter (currently only 'text' is supported) and a reference to the
transformation function.
If you define an entry filter you will also want to define a configuration option to turn the filter on and off (see below). Your function should check the value of the option for the given notebook and, if it is not set, return an unaltered version of the text.
Keep in mind that entry filters are cumulative; a user may enable more than one, and the results of one will be fed into the next. There is no guarantee of the order in which the filters will be run.
Examples: This is basically all the entry/filter
plugins do.
You can allow the user to make changes to the way your plugin
operates through NewsBruiser's integrated configuration interface. You
do this by creating an options.conf file in the plugin
directory. You can access the value of an option for a particular
notebook by calling getOptionValue on the notebook,
and passing in the name of the option.
NewsBruiser's configuration interface is provided by a library
called "I Want Options", in nb/lib/IWantOptions.py. It
has way too many features to mention here, but it NewsBruiser's main
options.conf file exercises almost all of them, the IWO
library contains internal documentation, and you can get an overview
of IWO from a paper I wrote on configuration frameworks, called Beyond
The Config File.
Examples: Each entry/filter plugin has a configuration
option to turn it on and off.
See the entry/annotate/Comments plugin for an example.
RSS 1.0 and 2.0 will call any registered hook methods when printing out their feed head (1.0) and their channel descriptor (1.0 and 2.0). See the notebook/annotate/License plugin for an example.
There is probably other stuff that I didn't add here when I added it to NewsBruiser. Please see the existing plugins for lots of ideas.
Right now there is no good way to link to plugin CGIs from NewsBruiser CGIs. The basic NewsBruiser CGIs are full of links to the CGIs provided by the included plugins. I can and plan to add hooks in specific places for plugins to provide HTML snippets, which should work for most purposes.
There are a few places in which a plugin can add form fields and form processing logic to the basic CGIs. Only those neccessary to support the outgoing trackback plugin have been implemented.
Templates defined in the core (like the entry template) sometimes contain template directives defined by plugins (like the comment plugin). Ideally the core template would call out to certain templating system hooks which would have been registered by the components. I know this problem is solvable, but have not yet come up with a satisfactory solution.