DokuWiki

It's better when it's simple

ユーザ用ツール

サイト用ツール


ja:devel:event_handlers

DokuWiki Event Handlers

DokuWikiでは、ユーザー独自のイベントやトリガーを作成することができます。そして、DokuWikiによって発動されるトリガーに対して、自分のイベントコードを実行できるように登録することができます。このページでは、DokuWikiによって発動されるトリガーに対して、イベントハンドラーをどう使い、どうコードするかを見ていきます。(DokuWikiのイベント一覧)

The Event Loop

まず、どのようにイベントが処理されるかを見ていくとわかりやすいでしょう。あるイベントの発生を知らされるためには、あなたのコードをそのイベント通知(notification)に登録しておく必要があります。あなたのコードをあるイベント通知に登録すると、通知に対する要求がそのイベントのリストの末尾に追加されます。このリストは、登録順に実行されていきます。このようにして、ひとつのイベント通知に対して複数のコードが順番に実行されることを実現しています。1)

DokuWikiがイベントに紐付けられたアクションのコードを処理するとき、すぐにその場で実行されるわけではありません。その代わり、このアクションに対するイベントが発生されます。たとえば、DokuWikiがwikiページを出力し始める時には、IO_WIKIPAGE_WRITEトリガーが発生され、イベント通知処理を始めます。

実際には2つのリストがあります:ひとつはDokuWikiのアクションの前(名前にBEFOREが付けられています)、もうひとつはアクションの後(AFTER)です。DokuWikiのあるアクションが実行される前に、BEFORE某に登録されたリクエストを順番に実行します。これにより、DokuWikiが何かを実行する前にあなたのコードを実行することができます。たとえば、IO_WIKIPAGE_WRITEの場合、ブラウザにページ内容が送られる前にそれを変更することができるのです。

DokuWikiのアクションが終わった後に、DokuWikiはAFTERに登録されたリクエストが順に実行されます。たとえば、TPL_ACT_RENDERイベントの場合、wikiページの後にページ内容を追加することができます。2)

DokuWikiのアクションはdefaultです。しかし、BEFOREリクエスト群の処理中に、defaultアクションを起こさないようにもできます。同様に、イベントハンドラーは他の未処理のイベントハンドラーを実行せずに飛ばすこともできます。

単純化した擬似コードで表すと、そのイベントプロセスはこのようになるでしょう。

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;
}

Registering an Event

イベントハンドラはEVENT_HANDLERクラスのregister_hook()メソッドを呼び出すことで登録でき、その使用はDokuWikiのevents pageで確認できます。

register_hook()メソッドの定義は次のようになっています。

void register_hook(string $event, string $advise,
    mixed &$obj, string $method, mixed $param = null, int $seq = 0) 
  • $event はイベントの名前です。たとえば、IO_WIKIPAGE_WRITE
  • $adviseBEFOREAFTER
  • $obj は参照側のオブジェクト。プラグインであれば$thisインスタンス、他のものであればNULL。コールバック関数の場合はグローバルスコープでなければならない。
  • $method イベント処理を実行するコールバックメソッドの名前。
  • $param はオプション。もしコールバックが何かしらのデータを必要とする場合に使う。
  • $seq はオプション。処理が実行される順番を制御する番号(release 2014-05-05 “Ponder Stibbons”から).

Global Scope

グローバルスコープからregister_hook()を呼び出す場合、 $objをnullにセットし、グローバル変数である$EVENT_HANDLERを直接使います。

$EVENT_HANDLER->register_hook( ... )

$EVENT_HANDLERDoku_Event_Handlerへの参照です。これは、DokuWikiで定義されたものもユーザー定義にものも、すべてのイベントの実行を制御しています。

Action plugins

Action plugins do not need direct access to the global $EVENT_HANDLER. They are specifically designed for adding handles to 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:

public function register(Doku_Event_Handler $controller) {
    $controller->register_hook('TPL_ACT_RENDER','AFTER',$this,'tpl_render');    
}
  • The event is TPL_ACT_RENDER, which is activated in 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 $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.

The Event Handler

The handler has this basic form:

/**
 * @param Doku_Event $event the Doku_Event object
 * @param mixed      $param value provided as fifth argument to register_hook()
 */ 
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 the fifth parameter in register_hook(). 3)

The Event Object

The authoritative specification for the event object Doku_Event is found on the event page and should be consulted.

The $event object has six fields:

  • 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.
  • 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 trigger_event() 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.
  • _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().
  • _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 handlers” but “this function does not prevent the default action taking place”.4)

Methods

    • 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 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 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 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 Event Loop).
    • 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:
      • $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
      • $action: This is the default action, most probably a function in the global scope.
      • $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.
    • 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 action5), since using this function replaces the event's default action with the $action parameter of trigger_event().

Examples

See event handlers code samples.

See also

1)
? FIXME When more handlers are registered, these will have a unknown, random order.
2)
同様に、BEFOREを使えばページ内容の前に何かを挿入することができます。
3)
DokuWiki's own events don't seem to use $param, but it is available if needed in user-designed events.
4)
Comment from inc/events.php
5)
For an example see DokuWiki's events page.
ja/devel/event_handlers.txt · 最終更新: 2014-08-17 05:31 by iobataya

特に明示されていない限り、本Wikiの内容は次のライセンスに従います: 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