The Firedrop2 Plugin System
Manual for the Firedrop plugin system. This includes using plugins, writing plugins, and brief docs for the standard plugins.
Firedrop2 is the blog client tool for discerning Python programmers. It now has a powerful mechanism for adding 'plugins' to it. This enables you to add new features like spell checking, email, etc. to Firedrop2.
Firedrop2 comes with several plugins as standard. You might need to enable them before you can use them, though. See Installing Plugins.
When you've done this, running Firedrop will show the 'plugin toolbar' with several buttons on it - I recommend starting with InteractiveGUI and SpellCheck. Clicking on their buttons will launch the respective plugin.
Configuring Firedrop2 to use plugins is very simple. You can either configure plugins to be available all the time, or just for individual blogs.
First of all the plugin files must be put in the 'plugins' directory. This is in the main firedrop2 directory.
Next you need to configure Firedrop2 to use the plugin. This is done in either the 'build.ini' for each site, or in a file called 'firedrop.ini' in the main firedrop2 directory. Both of these recognise a plugins keyword, which should be a list of all the plugins to use.
The name to use for the plugin is the name of the main filename minus the '.py'. For example, two of the standard plugin files are 'InteractiveGUI.py' and 'FireSpell.py'. The line to include in the config file is :
plugins = 'InteractiveGUI', 'FireSpell'
And that's all there is to it. If your distribution of Firedrop doesn't have a 'firedrop.ini', then just create one with any text editor. There may be additional steps for individual plugins of course. For example, FireSpell, the spell checker, needs a recent version of PyEnchant  to be installed.
This section briefly describes using the standard plugins that come with Firedrop.
ROT13 and Hello are simple example plugins by Hans Nowak. They illustrate creating plugins, and accessing mainframe attributes through them.
FireSpell is a spell checker for Firedrop2. It uses the PyEnchant module by Ryan Kelly. It needs version 1.1.2 or more recent.
FireSpell probably comes enabled by default. In case it doesn't, see Installing Plugins for the steps to install it. Even if your version of Firedrop comes with the FireSpell files, you may need to add the following line to either 'firedrop.ini' or 'build.ini' :
plugins = ['FireSpell']
To use FireSpell, select the entry you want to spell check and hit the SpellCheck button. This activates FireSpell, which should be straightforward to use. Any words you Add to Dict will be saved in a plain text file called 'pwl.txt' in the plugins directory.
PyEnchant comes with dictionaries for several languages. The default is 'en_US', meaning US English. You can choose any of the alternatives from the drop down list on FireSpell. Choosing a new language will cause this language to be the default next time FireSpell is started. For more dictionaries, follow the instructions for PyEnchant.
If you are a non-native English speaker, you may be interested in the alternative set of dictionaries available for FireSpell. You can find these at : http://lingucomponent.openoffice.org/spell_dic.html.
The dictionary file needs to go in the myspell folder in your PyEnchant distribution. On windows this would typically be at C:\Python24\Lib\site-packages\enchant\share\enchant\myspell (or similar).
FireMail is a plugin that allows you to email your current post. This is a feature of Blogger that I missed , so I've implemented it as a plugin. It is capable of sending HTML emails or text. When sent as HTML the text version of the post is also embedded so that people who don't like (or can't receive) HTML emails will see the text version.
FireMail generates the HTML using a file called 'firemail_template.html'. The mail server configuration should be done in a file called 'firemail.ini'. It first looks for these files in the site directory, if it doesn't find them there it looks in the plugin directory. This allows you to have different settings for each blog, or one setting that applies to all your blogs.
Editing the config file causes the changes to be saved. You will need to give it the name of your mail server. If you need to log in, it will need your username and password.
The 'to address' can be a single email address, or a comma separated list. Some email servers won't allow you to send email if you don't supply a 'from' address.
The template file uses the normal Firedrop2 template system. If you correctly set <base href=".... in the head of your template, then local references in the generated HTML ought to be resolved correctly when the email is received.
InteractiveGUI is a plugin for programmers. It gives you an interactive shell into Firedrop2.
This means that all the attributes of mainframe are available as local variables. The mainframe itself is present as self.
A useful value to inspect is active_entry, which is the currently selected entry . You can access the main editor pane as editor. It's fully dynamic - try changing entry and watch editor.Value change.
It's particularly useful when creating new plugins.
att_list = locals().keys()
Another plugin is called 'OutBox'. It's aimed at programmers. It is only useful for Windows users who run firedrop.pyw.; it will run on Mac OS X, but only for displaying errors (see below).
Once activated, it displays output from sys.stdout and sys.stderr (that would normally be lost) in a display box. This is useful for debugging - you can still see the output of print statements without having to have a console box hanging around.
Once activated for the first time it caches all output, even when closed. It's not enabled by default, of course.
Note that if you enable it, you should always put it last in the list of plugins :
plugins = 'InteractiveGUI', 'FireSpell', 'OutBox'
That's because if you have turned on debugging, as soon as OutBox is activated it will grab all of the debug print statements you would normally see.
New in Firedrop2 version 0.2.2 is the Themes plugin. This provide a choice of several different looks for your site. It's useful for new users who don't have a detailed knowledge of CSS stylesheets, or templates, but still would like to be able to vary the look of their site.
Each theme lives in the Themes folder inside the Firedrop folder. Each theme is comprised of a stylesheet and some templates, as described above. To select a Theme, click on the Themes plug-in button on the lower toolbar. You'll get the following dialog (as seen in Ubuntu Linux).
If you click on the name of a theme in the pull-down list, you'll see the description for that theme, and below it, a screen capture of a blog page using the theme.
When you select a theme, a couple of things happen :
At the present, only the weblog type has stylesheets applied to its templates. If you'd like to help by extending the themes to the other site types (article collection & item lists), please jump in!
If you would like to add a theme to the Firedrop project, by all means make a submission. Here's how :
Creating new plugins is not too difficult. You'll need a basic understanding of Wax . Thankfully this is very easy to learn and use. For help on learning Wax, or coding plugins for Firedrop, join the Wax Mailing List.
Every plugin must have a plugin class, which will be imported by Firedrop2.
This class should be named pluginnamePlugin. 'pluginname' is the plugin filename without the '.py', and the same name that should appear in build.ini/firedrop.ini for Firedrop2 to use the plugin.
This class should have an OnClick method, which will be called when the plugin button is used. OnClick receives one argument in addition to the usual self - this is mainframe which is actually the main Firedrop instance. Through this you (as a programmer) have access to all the entries and functions in the currently opened Firedrop.
This is easily illustrated with a basic example :
class SillyExamplePlugin: button_text = 'Silly Example' def OnClick(self, mainframe): print mainframe.editor.Value
Save the above code as SillyExample.py, put it in the plugin directory, and add 'SillyExample' to your 'firedrop.ini'. When you run Firedrop you'll see a new button 'Silly Example' on the plugin toolbar. Pressing this causes the contents of the main editor window to be dumped on stdout .
You'll notice the 'magic' class variable button_text. If this is present then its value is used for the plugin button.
Beyond this, writing plugins is simply a case of knowing the attributes of mainframe. You probably also want to know Wax : both to understand the methods available for elements of mainframe, and to construct a GUI for your plugin.
Attributes of mainframe include :
See the InteractiveGUI Manual for a way to explore these objects live.
mainframe.editor in particular is the wax TextBox that forms the main display. You can get and set its value through mainframe.editor.Value = 'something' and this_entry = mainframe.editor.Value. Note that setting Value directly like this won't mark the entry as modified. If the user navigates away from this entry without saving, the changes will be lost. You'll need to call mainframe.editor.Modified = True to do this.
Most plugins (but not all) will have their own GUIs. It makes sense to do this using Wax, with mainframe as the parent frame.
There are basically three possible techniques :
It's perfectly possible that your plugin doesn't need a GUI. It may just transform text. Pressing the plugin button causes an action on the entry, but doesn't launch a new window. See the example ROT13 plugin.
Code like this is probably better implemented as a method of textmanipulator and added as a menu option. There's no reason it shouldn't be done with a plugin though. You could use mainframe.fd2manager.getter() and mainframe.fd2manager.setter(new_text) to work with the currently selected text, or alternatively use the whole current entry.
If you want your plugin to launch as a child window you can create a subclass of Frame in the usual way. mainframe is the parent window. This can run alongside the main program, or you can set 'stay_on_top'.
See the InteractiveGUI plugin for a plugin that runs alongside Firedrop2. This plugin includes code that checks to make sure you only have one InteractiveGUI launched at a time. If there is already one open, pressing the plugin button just sets the focus to that window.
In practice this is likely to be the most common way of writing plugins. Create your plugin as a dialog and call ShowModal. Firedrop2 will freeze until your plugin has returned. If you do this, with mainframe as the parent, you can access the attributes of mainframe through self.Parent.
See FireSpell for an example of this behaviour. In this case FireSpell is a subclass of CustomDialog which is the most flexible dialog to build on.
When the plugin returns, the OnClick of the pluginnamePlugin class will have to make permanent any changes to the entry. One way to do that is for the plugin to directly set editor.Value. In this case you will need to do something like self.Parent.editor.Modified = True, so that Firedrop knows the editor pane has been changed.