For Practical Code Examples See: Sample Code
DokuWiki users can create and trigger their own events and they can register to be notified of events triggered by DokuWiki. This documentation looks at how to use and write handlers for the events which are triggered by Dokuwiki and are described in the DokuWiki events_list. What follows is based on my own experience with plugins and event handlers and is at least in part meant to clarify things for myself as well as to help others to implement these extremely useful features.
— Myron Turner 2007/11/03 12:19
To begin with, it's helpful to understand how events are processed. To be notified of an event, your code must register to receive the notification. Registering places your request for notification on a list of requests for the event. The list is a first come, first serve array; that is, it's treated as a stack where each next request is pushed on the end of the list. This means it's possible to implement more than one handler for the same event.
When DokuWiki processes an action that has an associated event, it does not perform this action immediately. Instead, it triggers an event for this action. For instance, when DokuWiki goes to write a wiki page, it triggers an IO_WIKIPAGE_WRITE event, which initiates the event notification process.
There are actually two lists: one for before and one for after DokuWiki performs its own action. These are designated by the 'BEFORE' and 'AFTER' keywords, used when registering for an event. Before processing its own action, DokuWiki loops through all the “BEFORE' requests, making its own action the last to be processed. This gives your code the opportunity to act on this event before DokuWiki gets to it. In the case of IO_WIKIPAGE_WRITE, for instance, you can make changes to the page content before it gets sent to the browser.
After performing its own action, DokuWiki loops through all the 'AFTER' requests. In the case of the TPL_ACT_RENDER event, for instance, it's possible to append content to the wiki page. 1)
DokuWiki's action is the default. But during the 'BEFORE' phase of some events, it's also possible to stop the default from taking place. Similarly, an event handler can short-circuit the event loop and prevent any handlers remaining on the stack from being executed.
In simplified pseudo code, the event process would look like this:
var $process_event = true; var $default_stopped = false; loop_through_BEFORE_List() { return if $process_event == false; } do_DokuWiki_Action() { return if $default_stopped; } var $process_event = true; loop_through_AFTER_List(){ return if $process_event == false; }
Event handlers are registered using the register_hook() function of the EVENT_HANDLER class, the specifications for which are found on Dokuwiki's events page. The function definition for register_hook() is as follows:
void register_hook(string $event, string $advise, mixed &$obj, string $method, mixed $param=NULL)
To call register_hook() from the global scope, you set $obj to NULL and use the global variable $EVENT_HANDLER:
$EVENT_HANDLER->register_hook( ... )
$EVENT_HANDLER is a reference to Doku_Event_Handler. It controls the execution of all events, both user-defined and DokuWiki-defined.
Action plugins do not need direct access to the global $EVENT_HANDLER. They are specifically designed handle DokuWiki events, and typically you would be calling register_hook from an action plugin.
In action plugins, event handlers are registered in the register() method, which all action plugins must implement. It takes one parameter, $controller, which is in effect an alias for $EVENT_HANDLER and which is used to register event handlers:
function register(&$controller) { $controller->register_hook('TPL_ACT_RENDER','AFTER',$this,'tpl_render'); }
The handler has this basic form:
/** * $event: Doku_Event object * $param: optional mixed variable */ function handler (&$event, $param) { // handler code }
When Doku_Event_Handler calls the handler function, it passes in two parameters, the current $event object and $param, which is designed to hold any additional data relevant to the event. $param is the $param that is passed through as a parameter in register_hook(). 2)
The authoritative specification for the event object (Doku_Event) is found on the DokuWiki site and should be consulted.
The $event object has six fields: