Plugins are cool. File::Find::Rule has them. Jerakeen likes them so much he wrote Bot::BasicBot::Pluggable.
CGI::Wiki is going to have plugins, too. 0.20 (which just escaped, some minutes ago) has (intentionally naive) metadata support, like so:
$wiki->write_node( "Reun Thai", "A restaurant", undef,
{ postcode => "W6 9PL",
category => [ "Thai Food", "Restaurant", "Hammersmith" ] } );
@nodes = $wiki->list_nodes_by_metadata( metadata_type => "category",
metadata_value => "Pub" );
(Earle has been an absolute star, testing out pre-releases and encouraging me to get around to adding this stuff.)
Plugin thoughts, as posted to the grubstreet list:
use CGI::Wiki;
use CGI::Wiki::Plugin::Location;
my $locator = CGI::Wiki::Plugin::Location->new;
my $wiki = CGI::Wiki->new;
$wiki->register_plugin($locator);
$wiki->write_node( "Jerusalem Tavern", "A good pub", $checksum,
{ os_x => 531674, os_y => 181950 } );
# Just retrieve the co-ordinates.
my ( $x, $y ) = $locator->coordinates( node => "Jerusalem Tavern" );
# Find the distance between two nodes.
my $distance = $locator->distance( from => "Jerusalem Tavern",
to => "Calthorpe Arms" );
# Find the nearest five other things that our wiki knows about.
my @others = $locator->find_nearest( node => "Jerusalem Tavern",
number => 5 );
The way the plugins will get hold of this data is by providing an on_write method that'll get called every time $wiki->write_node is called, with arguments like so:
$plugin->on_write( node => $node_name,
version => $version_number,
content => $content,
checksum => $checksum,
metadata => \%user_defined_metadata );
This will happen after the node data is all written, but before any lock is released. The user-defined metadata will already have been stored in the backend but it is available here for you to do what you will with it.
A plugin named, for example, CGI::Wiki::Plugin::Foo::Bar, will have free read-write access to any/all tables in the wiki's storage backend named like plugin_foo_bar* - for non-database backends if anyone ever writes one, there can be a similar namespace protection. So the CGI:Wiki::Plugin::Location plugin might store all its doo-dads in the 'plugin_location_os_coords' table, for example. This does mean that plugin authors have to care about differences between databases, but I'm strongly disinclined to try and invent a database-independent layer to sit on top of CGI::Wiki::Store::Database and cope with all possible imaginable circumstances.
Another plugin that I've put a small amount of thought into is one to cope with a hierarchy of categories.
And can someone tell me which tags to use to put code in so I don't have to put <br /> everywhere please? :)