Callbacks allow plugins to override behavior in PyBlosxom or provide additional behavior. The callback mechanism actually encompasses a series of different functions. Callbacks can act as handlers, as notifiers, and also as modifiers.
In the case of handler callbacks, PyBlosxom will query each plugin implementing the callback until one of the plugins returns that it has handled the callback. At that point, execution of handling code stops. If none of the plugins handle the callback, then PyBlosxom will run its default behavior code.
In the case of notifier callbacks, PyBlosxom will notify each plugin implementing the callback regardless of return values.
In the case of modifier callbacks, PyBlosxom will query each plugin implementing the callback passing in some input. It takes the output from the callback function and passes that in as input to the next callback function. In this way, each plugin has a chance to modify and transform the data.
There's no reason you can't implement a handler-type callback and use it for notification purposes--that's fine. You should know that in the case of handler callbacks and modifier callbacks, the return value that your plugin gives will affect PyBlosxom's execution.
There are a series of callbacks in PyBlosxom that have equivalents in blosxom 2.0. The names are sometimes different and in most cases the arguments the PyBlosxom versions take are different than the blosxom 2.0 versions. Even so, the PyBlosxom versions serve the same purpose as the blosxom 2.0 versions.
This isn't very interesting unless you're trying to implement the functionality of a blosxom 2.0 plugin in Python for PyBlosxom.
The available blosxom renderer callbacks are:
cb_head - corresponds to blosxom 2.0 head
cb_date_head - corresponds to blosxom 2.0 date
cb_story - corresponds to blosxom 2.0 story
cb_foot - corresponds to blosoxm 2.0 foot
Additionally, we have these lifecycle callbacks available:
the blosxom 2.0 entries callback is handled by cb_filelist
the blosxom 2.0 filter callback is handled by cb_prepare
the blosxom 2.0 sort callback can sort of be handled by cb_prepare depending on what you're trying to do
The prepare callback is called in the default blosxom handler after we've figured out what we're rendering and before we actually go to the renderer.
Plugins should implement cb_prepare to modify the data dict which is in the Request. Inside the data dict is entry_list (amongst other things) which holds the list of entries to be renderered (in the order they will be rendered).
Functions that implement this callback will get an args dict containing:
request - The Request object at the particular moment
Functions that implement this callback can return whatever they want--it doesn't affect the callback chain.
Example of a cb_prepare function in a plugin:
Example 10-1. Example of cb_prepare usage
def cb_prepare(args): """ This plugin shows the number of entries we are going to render and place the result in $countNoOfEntries. """ request = args['request'] data = request.getData() config = request.getConfiguration() # Can anyone say Ternary? :) IF = lambda a,b,c:(a() and [b()] or [c()])[0] num_entry = config['num_entries'] entries = len(data['entry_list']) data['countNoOfEntries'] = IF(num_entry > entries, num_entry, entries)
The logrequest callback is used to notify plugins of the current PyBlosxom request for the purposes of logging.
Functions that implement this callback will get an args dict containing:
filename - a filename (typically a base filename)
return_code - A HTTP error code (e.g 200, 404, 304)
request - a Request object
Functions that implement this callback can return whatever they want--it doesn't affect the callback chain.
cb_logrequest is called after rendering and will contain all the modifications to the Request object made by the plugins.
An example input args dict is like this::
The filelist callback allows plugins to generate the list of entries to be rendered. Entries should be EntryBase derivatives--either by instantiating EntryBase, FileEntry, or creating your own EntryBase subclass.
Functions that implement this callback will get an args dict containing:
request - the PyBlosxom Request
Functions that implement this callback should return None if they don't plan on generating the entry list or a list of entries. if they do. When a function returns None, the callback will continue to the next function to see if it will return a list of entries. When a function returns a list of entries, the callback will stop.
The filestat callback allows plugins to override the mtime of the entry. One of the contributed plugins uses this to set the mtime to the time specified in the entry's filename.
Functions that implement this callback will get an args dict containing:
filename - the filename of the entry
mtime - the result of an os.stat on the filename of the entry
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.
The pathinfo callback allows plugins to parse the HTTP PATH_INFO item. This item is stored in the http dict of the Request object. Functions would parse this as they desire, then set the following variables in the data dict of the Request object:
bl_type - (dir|file)
pi_bl - typically the same as PATH_INFO
pi_yr - yyyy
pi_mo - (mm|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
pi_da - dd
root_datadir - full path to the entry folder or entry file on filesystem
flavour - The flavour gathered from the URL
Functions that implement this callback will get an args dict containing:
request - a Request object
Functions that implement this callback should make the modifications to the data dict in place--no need to return anything.
The renderer callback allows plugins to specify a renderer to use by returning a renderer instance to use. If no renderer is specified, we use the default blosxom renderer.
Functions that implement this callback will get an args dict containing:
request - the PyBlosxom Request
Functions that implement this callback should return None if they don't want to specify a renderer or the renderer object instanct if they do. When a function returns a renderer instance, processing stops.
The entryparser callback allows plugins to register the entryparsers they have. Entry parsers are linked with a filename extension. For example, the default blosxom text entry parser will be used for any file ending in ".txt".
Functions that implement this callback will get the entryparser dict consisting of file extension -> entry parsing function pairs.
Functions that implement this callback should return the entryparser dict after modifying it.
The preformat callback acts in conjunction with the entryparser that handled the entry to do a two-pass formatting of the entry.
Functions that implement cb_preformat are text transformation tools. Once one of them returns a transformed entry, then we stop processing.
Functions that implement this callback will get an args dict containing:
parser - a string that indicates whether a preformatter should run
story - a list containing lines of text (with '\n' included)
request - a Request object
Functions that implement this callback should return None if they didn't modify the story or a single story string.
The postformat callback allows plugins to make further modifications to entry text. It typically gets called after a preformatter by the entryparser. It can also be used to add additional properties to entries. The changes from postformat functions are saved in the cache (if the user has caching enabled). As such, this shouldn't be used for dynamic data like comment counts.
Examples of usage:
adding a word count property to the entry
using a macro replacement plugin (Radio Userland glossary)
acronym expansion
a 'more' text processor
Functions that implement this callback will get an args dict containing:
entry_data - a dict that minimally contains a "title" and a "story"
request - a Request object
Functions that implement this callback don't need to return anything--modifications to the entry_data dict are done in place.
The start callback allows plugins to execute startup/initialization code. Use this callback for any setup code that your plugin needs, like:
reading saved data from a file
checking to make sure configuration variables are set
allocating resources
cb_start is different in PyBlosxom than in blosxom | |
---|---|
The cb_start callback is slightly different than in blosxom in that cb_start is called for every PyBlosxom request regardless of whether it's handled by the default blosxom handler. In general, it's better to delay allocating resources until you absolutely know you are going to use them. |
Functions that implement this callback will get an args dict containing:
request - a Request object
Functions that implement this callback don't need to return anything.
The start callback allows plugins to execute teardown/cleanup code, save any data that hasn't been saved, clean up temporary files, and otherwise return the system to a normal state.
Examples of usage:
save data to a file
clean up any temporary files
Functions that implement this callback will get an args dict containing:
request - a Request object
Functions that implement this callback don't need to return anything.
cb_end is different in PyBlosxom than in blosxom | |
---|---|
The cb_end callback is called for every PyBlosxom request regardless of whether it's handled by the default blosxom handler. This is slightly different than blosxom. |
The head callback is called before a head flavour template is rendered.
cb_head is called before the variables in the entry are substituted into the template. This is the place to modify the head template based on the entry content. You can also set variables on the entry that will be used by the cb_story or cb_foot templates. You have access to all the content variables via entry.
Blosxom 2.0 calls this callback 'head'.
Functions that implement this callback will get an args dict containing:
request - the Request object
renderer - the BlosxomRenderer that called the callback
entry - a EntryBase to be rendered
template - a string containing the flavour template to be processed
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.
Example in which we add the number of entries being rendered to the $blog_title variable:
The date_head callback is called before a date_head flavour template is rendered.
cb_date_head is called before the variables in the entry are substituted into the template. This is the place to modify the date_head template based on the entry content. You have access to all the content variables via entry.
Blosxom 2.0 calls this callback 'date'.
Functions that implement this callback will get an args dict containing:
request - the Request object
renderer - the BlosxomRenderer that called the callback
entry - a EntryBase to be rendered
template - a string containing the flavour template to be processed
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.
The story callback gets called before the entry is rendered.
The template used is typically the story template, but we allow entries to override this if they have a "template" property. If they have the "template" property, then we'll use that template instead.
cb_story is called before the variables in the entry are substituted into the template. This is the place to modify the story template based on the entry content. You have access to all the content variables via entry.
Blosxom 2.0 calls this callback 'story'.
Functions that implement this callback will get an args dict containing:
request - the Request object
renderer - the BlosxomRenderer that called the callback
entry - a EntryBase to be rendered
template - a string containing the flavour template to be processed
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.
The story_end callback is is called after the variables in the entry are substituted into the template. You have access to all the content variables via entry.
Functions that implement this callback will get an args dict containing:
request - the Request object
renderer - the BlosxomRenderer that called the callback
entry - a EntryBase to be rendered
template - a string containing the flavour template to be processed
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.
The foot callback is called before the variables in the entry are substituted into the foot template. This is the place to modify the foot template based on the entry content. You have access to all the content variables via entry.
Blosxom 2.0 calls this callback 'foot'.
Functions that implement this callback will get an args dict containing:
request - the Request object
renderer - the BlosxomRenderer that called the callback
entry - a EntryBase to be rendered
template - a string containing the flavour template to be processed
Functions that implement this callback must return the input args dict whether or not they adjust anything in it.