DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:event_handlers

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
devel:event_handlers [2013-11-19 00:14] Klap-indevel:event_handlers [2023-09-02 13:37] (current) Klap-in
Line 5: Line 5:
 ===== The Event Loop  ===== ===== The Event Loop  =====
  
-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 more handlers are registered, these will have a unknown, random order.+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-served 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 more handlers are registered, these will have a unknown, random order.
  
 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 [[devel:event:IO_WIKIPAGE_WRITE]] event, which initiates the event notification process. 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 [[devel:event:IO_WIKIPAGE_WRITE]] event, which initiates the event notification process.
Line 11: Line 11:
 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 [[devel:event:IO_WIKIPAGE_WRITE]], for instance, you can make changes to the page content before it gets sent to the browser.  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 [[devel:event: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 [[devel:event:TPL_ACT_RENDER]] event, for instance, it's possible to append content to the wiki page. ((Similarly, using ''BEFORE'', you can prepend content.))+After performing its own action, DokuWiki loops through all the ''AFTER'' requests. In the case of the [[devel:event:TPL_ACT_RENDER]] event, for instance, it's possible to append content to the wiki page.((Similarly, using ''BEFORE'', you can prepend content.))
  
 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. 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.
Line 37: Line 37:
  
 ===== Registering an Event ===== ===== Registering an Event =====
-Event handlers are registered using the ''register_hook()'' function of the ''EVENT_HANDLER'' class, the specifications for which are found on Dokuwiki's [[events#registering_to_receive_an_event|events page]].+Event handlers are registered using the [[xref>register_hook()]] function of the [[xref>EventHandler]] class, the specifications for which are found on Dokuwiki's [[events#registering_to_receive_an_event|events page]].
 The function definition for ''register_hook()'' is as follows: The function definition for ''register_hook()'' is as follows:
 <code php> <code php>
 void register_hook(string $event, string $advise, void register_hook(string $event, string $advise,
-    mixed &$obj, string $method, mixed $param = null) +    object $obj, string $method, mixed $param = null, int $seq = 0
 </code> </code>
     * ''$event'' is the name of the event, for instance [[devel:event:IO_WIKIPAGE_WRITE]]      * ''$event'' is the name of the event, for instance [[devel:event:IO_WIKIPAGE_WRITE]] 
Line 48: Line 48:
     * ''$method'' is the name of the callback function which will handle the event     * ''$method'' is the name of the callback function which will handle the event
     * ''$param'' is an optional container for any data which the callback might require     * ''$param'' is an optional container for any data which the callback might require
 +    * ''$seq'' is an optional sequence number used to control the order in which hooks are executed (since release 2014-05-05 "Ponder Stibbons").  
  
 ==== Global Scope ==== ==== Global Scope ====
 To call ''register_hook()'' from the global scope, you set ''$obj'' to null and use To call ''register_hook()'' from the global scope, you set ''$obj'' to null and use
-the global variable ''$EVENT_HANDLER'':+the global variable [[xref>$EVENT_HANDLER]]:
 <code php> <code php>
 $EVENT_HANDLER->register_hook( ... ) $EVENT_HANDLER->register_hook( ... )
 </code> </code>
-''$EVENT_HANDLER'' is a reference to ''Doku_Event_Handler''. It controls the execution of all events, both user-defined and DokuWiki-defined.+''$EVENT_HANDLER'' is a reference to ''dokuwiki\Extension\EventHandler''. It controls the execution of all events, both user-defined and DokuWiki-defined.
  
 ==== Action plugins ==== ==== Action plugins ====
Line 62: Line 63:
 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: 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:
 <code php> <code php>
-public function register(Doku_Event_Handler $controller) { +use dokuwiki\Extension\EventHandler; 
-    $controller->register_hook('TPL_ACT_RENDER','AFTER',$this,'tpl_render');    +... 
 +public function register(EventHandler $controller) { 
 +    $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 
 +                                                          'templateRender');
 } }
 </code> </code>
  
     * The event is [[devel:event:TPL_ACT_RENDER]], which is activated in ''[[xref>inc/template.php]]'' by the function which dispatches the page to be formatted and printed.     * The event is [[devel:event:TPL_ACT_RENDER]], which is activated in ''[[xref>inc/template.php]]'' by the function which dispatches the page to be formatted and printed.
-    * The event handler is ''tpl_render()'', which will be found in the plugin object.+    * The event handler is ''templateRender()'', which will be found in the plugin object.
     * The ''$this'' parameter, which points to the plugin object, will give DokuWiki's event module access to the handler.     * The ''$this'' parameter, which points to the plugin object, will give DokuWiki's event module access to the handler.
     * Finally, the handler is to be called **after** DokuWiki formats the page content.     * Finally, the handler is to be called **after** DokuWiki formats the page content.
Line 76: Line 80:
 The handler has this basic form: The handler has this basic form:
 <code php> <code php>
 +use dokuwiki\Extension\Event;
 +...
 /** /**
- * @param Doku_Event $event the Doku_Event object + * @param Event $event the Event object 
- * @param mixed      $param value provided as fifth argument to register_hook()+ * @param mixed $param value provided as fifth argument to register_hook()
  */   */ 
-function handler (&$event, $param) {+public function handler (Event $event, $param) {
     // handler code     // handler code
 } }
 </code> </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 the fifth parameter in [[event_handlers#registering_an_event|register_hook()]].+When EventHandler 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 the fifth parameter in [[event_handlers#registering_an_event|register_hook()]].
 ((DokuWiki's own events don't seem to use ''$param'', but it is available if needed in user-designed events.)) ((DokuWiki's own events don't seem to use ''$param'', but it is available if needed in user-designed events.))
  
  
 ==== The Event Object ==== ==== The Event Object ====
-The authoritative specification for the event object ([[xref>Doku_Event]]is found on the +The authoritative specification for the event object [[xref>Event]] is found on the 
 [[events#event_object|event page]] and should be consulted. [[events#event_object|event page]] and should be consulted.
  
Line 95: Line 101:
     * ''name'': Event Name;     * ''name'': Event Name;
     * ''data'': Specific to each event, data may include, page content, headers, meta data, objects, the current action (e.g. edit, index), whatever is needed of for the execution of the event; it may also hold no data, and it has no fixed structure: it may be a string, array, multidimensional array, object.     * ''data'': Specific to each event, data may include, page content, headers, meta data, objects, the current action (e.g. edit, index), whatever is needed of for the execution of the event; it may also hold no data, and it has no fixed structure: it may be a string, array, multidimensional array, object.
-    * ''result'': First it holds the return value from the default handler, which can then be consulted by an ''AFTER'' handler. It can then be modified by an ''AFTER'' handler, in which case it might be information for any subsequent ''AFTER'' handlers. Ultimately, it will be returned to the ''[[#methods|trigger_event()]]'' function. In most case this value is either ''true'', if the default action has taken place, or ''null'' if it hasn't.+    * ''result'': First it holds the return value from the default handler, which can then be consulted by an ''AFTER'' handler. It can then be modified by an ''AFTER'' handler, in which case it might be information for any subsequent ''AFTER'' handlers. Ultimately, it will be returned to the [[#methods|Event::createAndTrigger()]] function. In most case this value is either ''true'', if the default action has taken place, or ''null'' if it hasn't.
     * ''canPreventDefault'':  ''true'' or ''false'', indicating whether or not the default action for this event can be stopped; this information is available from DokuWiki's [[events list]].     * ''canPreventDefault'':  ''true'' or ''false'', indicating whether or not the default action for this event can be stopped; this information is available from DokuWiki's [[events list]].
-    * ''_default'':  ''true'' or ''false'', indicating whether the default action for this event should be enabled; its default value is true but can be set to false by calling $event%%->%%preventDefault(). +    * protected ''runDefault'':  ''true'' or ''false'', indicating whether the default action for this event should be enabled; its default value is true but can be set to false by calling ''$event%%->%%preventDefault()''
-    * ''_continue'':  This value defaults to ''true''. If ''$event%%->%%stopPropagation()'' is called, it is set to false, stopping "any further processing of the event by event handlersbut "this function does not prevent the default action taking place".((Comment from [[xref>inc/events.php]]))+    * protected ''mayContinue'':  This value defaults to ''true''. If ''$event%%->%%stopPropagation()'' is called, it is set to false, stopping any further processing of the event ''BEFORE'' or ''AFTER'' handlers registered for this event, but this function does not prevent the default action taking place.
  
 ==== Methods ==== ==== Methods ====
  
     - ''$event%%->%%[[xref>preventDefault()]]''     - ''$event%%->%%[[xref>preventDefault()]]''
-        * Calling this method from a ''BEFORE'' handler prevents the default action taking from place; it has no effect if called from an ''AFTER'' handler. It sets ''$event%%->%%_default'' to ''false''. Being able to prevent the default action has considerable utility. It can stop a page from being cached when used with the [[devel:event:PARSER_CACHE_USE]] event. It can also prevent a page from being sent to the browser at various stages of the rendering and output process, each of which is represented by an event. One enticing idea is preventing the [[devel:event:TPL_ACT_UNKNOWN]] default to set up your own action in response to an unrecognized action request. However, this idea would not work because it is blocked the by ''action_clean()'' method in inc/action.php. See the [[events list]] on the DokuWiki site for details and possibilities.+        * Calling this method from a ''BEFORE'' handler prevents the default action taking from place; it has no effect if called from an ''AFTER'' handler. It sets ''$event%%->%%runDefault'' to ''false''. Being able to prevent the default action has considerable utility. It can stop a page from being cached when used with the [[devel:event:PARSER_CACHE_USE]] event. It can also prevent a page from being sent to the browser at various stages of the rendering and output process, each of which is represented by an event. One enticing idea is preventing the [[devel:event:TPL_ACT_UNKNOWN]] default to set up your own action in response to an unrecognized action request. However, this idea would not work because it is blocked the by ''action_clean()'' method in inc/action.php. See the [[events list]] on the DokuWiki site for details and possibilities.
     - ''$event%%->%%[[xref>stopPropagation()]]''     - ''$event%%->%%[[xref>stopPropagation()]]''
-        * Calling this method sets ''$event%%->%%_continue'' to ''false'' and stops any further processing of the event by event handlers; it does not prevent the default action taking place. It comes into play where you have set more than one handler for the same event. If you have registered an event for both ''BEFORE'' and ''AFTER'' execution, canceling the ''BEFORE'' does not stop propagation of the ''AFTER'' events. (See the above section on the [[#the_event_loop|Event Loop]]). +        * Calling this method sets ''$event%%->%%mayContinue'' to ''false'' and stops any further processing of the event by event handlers; it does not prevent the default action taking place. It comes into play where you have set more than one handler for the same event. If you have registered an event for both ''BEFORE'' and ''AFTER'' execution, canceling the ''BEFORE'' does not stop propagation of the ''AFTER'' events. (See the above section on the [[#the_event_loop|Event Loop]]). 
-    - ''mixed [[xref>trigger_event|trigger_event($name, &$data, $action=null, $canPreventDefault=true)]]'' +    - ''mixed [[xref>Event::createAndTrigger|Event::createAndTrigger(string $name, mixed &$data, callable $action=null, bool $canPreventDefault=true)]]'' 
-        * This is a global function, not a method of the ''Doku_Event'' class. Calling this function enables the triggering of a user-defined event. Its parameters are as follows:+        * This is a global function. Calling this function enables the triggering of a user-defined event. Its parameters are as follows:
              * ''$name'': This is the name of the event. If you implement your own event, then this is the name of that event.              * ''$name'': This is the name of the event. If you implement your own event, then this is the name of that event.
              * ''$data'': Whatever is required for your data              * ''$data'': Whatever is required for your data
Line 113: Line 119:
              * ''$canPreventDefault'': ''true'' or ''false'', to indicate whether or not the default action can be stopped. In user-defined events, this can be left at the default value of ''true''.              * ''$canPreventDefault'': ''true'' or ''false'', to indicate whether or not the default action can be stopped. In user-defined events, this can be left at the default value of ''true''.
             * mixed return value: This is whatever is stored in the event's property ''$event%%->%%result''.             * mixed return value: This is whatever is stored in the event's property ''$event%%->%%result''.
-        *  It's possible to use this function to trigger a standard DokuWiki event, but this would require careful coding and a knowledge of when and how the DokuWiki event is processed. Moreover, triggering a standard event doesn't prevent it from being triggered by DokuWiki. It would also have to be an event which doesn't have a default action((For an example see DokuWiki' [[events#examples|events]] page.)), since using this function replaces the event's default action with the ''$action'' parameter of ''trigger_event()''.+        *  It's possible to use this function to trigger a standard DokuWiki event, but this would require careful coding and a knowledge of when and how the DokuWiki event is processed. Moreover, triggering a standard event doesn't prevent it from being triggered by DokuWiki. It would also have to be an event which doesn't have a default action((For an example see DokuWiki' [[events#examples|events]] page.)), since using this function replaces the event's default action with the ''$action'' parameter of ''Event::createAndTrigger()''.
  
 =====Examples===== =====Examples=====
Line 119: Line 125:
  
 =====See also ===== =====See also =====
-  * [[Events list]] + 
-  * [[Events]] +  The [[Events|Event system]] 
-  * [[Action plugins]]+  * [[Events List]] with existing events. 
 +  * Use [[Action plugins]] to register handlers on events.
devel/event_handlers.1384816495.txt.gz · Last modified: 2013-11-19 00:14 by Klap-in

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki