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.
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:
That's all you need. Write those lines in a file, call it
import vellum.Entry
vellum.Entry.Entry.colour = "red"
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.
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:
You can now add <%=entry.timeOfDay()%> to your template, and that
entry's time of day will be written.
# 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
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.
and your blog should now ping weblogs.com with an update when it
updates.
# 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)
| 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 |
Your plugin should define a __pluginname__ and __description__ string, which is then displayed on the plugins page.