[dokuwiki] Re: the event system

Chris Smith wrote:
Jason Grout wrote:

Okay, it's done.

There's a newpagetemplate action plugin that will look for the "newpagetemplate" parameter in $_REQUEST. If the parameter exists, then the page is loaded as a template, with the substitutions currently offered by the namespace templates. Note that this overrides the namespace template.

I have a quick question about my implementation. In the following, a BEFORE callback is an event handler registered with the BEFORE advisement (sp?), and similarly for an AFTER callback. I implemented the plugin as a BEFORE callback, then manually set the $event->result variable and called $event->preventDefault(). Is that all right to do in a BEFORE callback? The documentation seems to indicate that you should only mess with $event->result in an AFTER callback. However, I'd just as soon not go through the expense of loading the default namespace template if I know I'm overriding it. I suppose I could make two callbacks, one BEFORE and one AFTER, with the BEFORE callback checking the $_REQUEST variable and preventing the default, while the AFTER callback actually loads the page, but that seems wasteful as well.

I've also patched the addnewpage plugin to take advantage of the newpagetemplate functionality. The new syntax is:

{{NEWPAGE>ns|:newpage:template}}

where the new page template follows the vertical bar. I posted the patch up to the addnewpage plugin discussion area.

Thanks again for everyone's help!

Jason

There aren't so many rules in how you do things in a plugin.

Okay, that clears up a few things. However, the structure was one of the biggest reasons I chose DokuWiki (PmWiki seemed like spaghetti code in comparison, for instance, but I didn't get to know it very well). I guess I love having a nice, clearly structured way of doing things. The hard part is making the structure as flexible as it needs to be, but still clear enough to be useful.


The method you have chosen seems sensible. If a plugin needs to modify an existing result it should handle the "AFTER" event - in so much as there is a result, it is guaranteed to exist. If a plugin provides a result "instead of" the DW result it really should do that using the "BEFORE" advise and call preventDefault(), that way you are maintaining the model that "AFTER" handlers will see the result. You're doing that. :-)

If this isn't clear in the documentation, please feel free to enhance it ;-)

Cheers,

Chris

PS. I think the above may be the argument I missed for the original three advise system.

before event - prepares the data
event - creates a result
after event - modifes a result

Under our present system, where order isn't guaranteed, one before handler that prepares the data may be called after a different handler that sets a result.

Any one for a change :D


(changing title to reflect a discussion on the event system)

So really my plugin should be _replacing_ the default event. It should be called after the BEFORE callbacks, replace the default event, and before the AFTER callbacks.

Here's an idea, taken from the Common Lisp object system (which is amazing, by the way :), but is also a natural extension of what we have here already.

There are three advisements: "BEFORE", "" (empty string), and "AFTER". Specifying "BEFORE" gives a BEFORE callback, "" gives a primary callback, and "AFTER" gives an AFTER callback. These are then called thusly:

- First, all BEFORE callbacks are called. It might be nice here to allow a callback to stop the propagation of BEFORE callbacks, jumping straight to primary callbacks. However, the job is to prepare data, so I can't stop the primary callbacks or AFTER callbacks. The only thing that the BEFORE callbacks should mess with is $data. - Second, all primary callbacks are called, with the default callback being called last. Again, any callback can stop the propagation (which also stops the default callback from being called). The job here is to fill $event->result with something meaningful. - Third, all AFTER callbacks are called. Again, we can stop the propagation at any time. The job here is to modify the data in $event->result. It would be nice if we could force an order to these callbacks, but that can wait for another day. When you say that order isn't guaranteed, I assume that it _is_ guaranteed that all BEFORE callbacks execute before the default method, which executes before all AFTER callbacks, but that the order of BEFORE callbacks isn't specified and the order of AFTER callbacks isn't specified.

It seems like it wouldn't be too hard to modify the existing system to be like the system described above (famous last words, yeah, I know). It would add a little structure to the existing system and make it more clear how to implement different callbacks.

After doing a bit of research into other systems that use events and triggers, here's something interesting that e107 wiki does ( http://wiki.e107.org/?title=Core_event_trigger ): You can register a file that is loaded and function that is executed when an event is triggered. The idea is to not have to parse every single callback function every time you load a page (is that DokuWiki does now?). I haven't done any profiling, (which is the first thing that needs to be done to see if this will speed up things), but if we cut down on the number of things we load, it can't be a bad thing. I'd love to see a huge speed increase in DokuWiki.


Thanks,

Jason

--
DokuWiki mailing list - more info at
http://wiki.splitbrain.org/wiki:mailinglist

Other related posts: