Vellum

Index > Plugins: developer documentation

If you don't intend to alter the way Vellum works, you don't need to read this documentation; plugins are the most advanced part of Vellum, and this documentation is designed for hackers who want to alter what Vellum does and how it does it.

Vellum plugins are Python files that are "installed" by dropping them into the vellum/plugins directory. A plugin can alter the way Vellum works in one of two ways: it can add attributes and methods to the existing Vellum objects, and it can add code to some of Vellum's internal processes.

Adding attributes and methods

Let's imagine that you wanted all your entries to have a colour attribute, which is set to "red". (This is a pretty simple and useless example, but it illustrates the principle). To add an attribute to all entries, you add it to the Entry class, which is called Entry in vellum.Entry from a plugin. So the plugin's code would be:

import vellum.Entry
vellum.Entry.Entry.colour = "red"
That's all you need. Write those lines in a file, call it colour.py, and drop that file in your vellum/plugins directory. You don't have to tell Vellum that you've added a new plugin; it will declare it automatically. From now on, every entry will have an entry.colour attribute, set to "red". So you could print entry.colour in your templates, for example.

A slightly more complex example of adding attributes and methods

Now, let us imagine that we want to have our blog display whether an entry was posted in the morning or the evening, by adding "Morning" or "Evening" after the time posted. You could implement this directly in the blog templates, but we'll say for convenience that you want entries to have a timeOfDay() method. The code for this might look like so:

# Import modules that we need
import time,vellum.Entry

# First create the function: note that we're going to attach it to
#  an Entry object as a method, so it will get called with one
#  parameter, self, which will be the entry.
def tOD(self):
    hour = time.localtime(self.posted)[3]
    if hour >= 0 and hour < 12:
        return "Morning"
    else:
        return "Evening"

# Now add that function to all entries
vellum.Entry.Entry.timeOfDay = tOD
You can now add <%=entry.timeOfDay()%> to your template, and that entry's time of day will be written.

Adding code to internal processes

Adding new attributes and new methods is all well and good, but what if you want to have your code run when something in Vellum happens? Say you want to do something to an entry when it's rebuilt? For this you use hooks. At various points during its processes, Vellum has a hook, a place where other code can run. If you want some code from your plugin to run at that point, you attach your code to that hook, and every time Vellum processes that hook, your code runs. Attach your code to a hook with vellum.hooks.register_hook(hook_name,function). Hooks are documented below. An important point to remember is that some hooks (and thus functions attached to them) are called with parameters, and some are not. You must make sure that your function is set up to take the appropriate parameters that will be passed to it, based on the hook to which it is attached, otherwise calling your function will die horribly and possibly leave your blog in an inconsistent state.

An example of attaching a function to a hook: imagine that you wanted to, when an entry was posted, send an ping to weblogs.com. This is best done once the entry has been saved and the web pages have been rebuilt by Vellum, so we'll attach to the entry-rebuild-post hook. A function attached to this hook is passed one parameter, an entry.

# Import appropriate modules
# Note that this requires XMLRPClib, which comes as standard with
#  Python 2.2, but must be added to your plugins directory for
#  earlier versions
import xmlrpclib,vellum.Blog,vellum.hooks

# Define the function to do the ping
def pingWeblogsCom(entry):
    # Get the blog's name and static URL
    blog = vellum.Blog.get(entry.blogid)
    svr = xmlrpclib.Server("http://rpc.weblogs.com/RPC2")
    svr.weblogUpdates.ping(blog.title,blog.staticurl)

# And attach that function to a hook
vellum.hooks.register_hook("entry-rebuild-post",pingWeblogsCom)
and your blog should now ping weblogs.com with an update when it updates.

Hook name When it runs Parameters passed
entry-save-pre Before an entry is saved entry, the entry that's being saved
entry-save-post After an entry is saved entry, the entry that's being saved
entry-rebuild-pre Before an entry is rebuilt entry, the entry that's being rebuilt
entry-rebuild-post After an entry is rebuilt entry, the entry that's being rebuilt
entry-listdisplay-print After each entry in the entry list is displayed entry, the entry that's just been displayed
entry-new-print Before the form to create a new entry is displayed
entry-new-save After the form to create a new entry is processed entry, the Entry object that has been created (but not yet saved)
form, the submitted form (as a cgi.FieldStorage object)
entry-edit-print Before the form to edit an existing entry is displayed
entry-edit-save After the form to edit an existing entry is processed entry, the Entry object that is being edited (but not yet re-saved)
form, the submitted form (as a cgi.FieldStorage object)
blog-displayentries-pre Before a blog's entries are displayed in the back end blog, the blog in question
blog-displayentries-post After a blog's entries are displayed in the back end blog, the blog in question
blog-rebuild-pre Before an entire blog is rebuilt blog, the blog in question
blog-rebuild-post After an entire blog is rebuilt blog, the blog in question
export-pre Before entries are exported
export-post After entries are exported
import-pre Before entries are imported
import-post After entries are imported

Names and pack drill

Your plugin should define a __pluginname__ and __description__ string, which is then displayed on the plugins page.