Processing page output on the fly


Sometimes it would be useful to process the output of the formatting engine before displaying it to visitors. This will allow actions to automatically reformat text in particular ways. For instance, all camelcase links could be uncamelized while still maintaining the underlying code on the page. It would also be nice if we could apply certain actions across the entire site. This is exactly what this code allows us to do.

The first step is deciding whether or not we want to process the entire page, including the header and the footer, or just the body content. The current incarnation is working at the level of the body content, but it can be easily extended to include the header and footer output as well.

Once we know what we're dealing with, we can find where it's coming into the wiki display process. The Run() method is handy for figuring this type of stuff out. In the case of the formatted body content, we find that it's loaded up by the page/show handler. So we have to open that up and replace the line that prints $this->page['body'] with the following code:

        // display page
        $global_actions = $this->LoadSingle('SELECT body FROM ' . $this->config['table_prefix'] . 'pages WHERE tag = \'GlobalActions\' AND latest = \'Y\'');
        $regex = "/\{\{(onpageload.*?)\}\}/s";
        if (preg_match($regex, $this->page['body'] . (isset($global_actions['body']) ? $global_actions['body'] : ''), $matches))
        {
            $onload_actions = $matches[1];
            $this->page['body'] = preg_replace($regex, '', $this->page['body']);
        }
        if ($this->config['allow_page_load_actions'] && $onload_actions)
        {
            echo $this->Action($onload_actions);
        }
        else
        {
            echo $this->Format($this->page['body'], 'wakka');
        }


As you can see, the new process only comes into the picture if the user has set the 'allow_page_load_actions' config variable to true.

The next thing we need to do is create a file called "onpageload.php" and save it in the actions directory. Here's the code:

if ($this->tag == 'GlobalActions') return;

if (!function_exists('_onpageload'))
{
    function _onpageload(&$wikka, $actions)
    {
        foreach ($actions as $name => $parameters)
        {
            if (!in_array($name, array('wikka_vars', 'runtime', 'onpageload')))
            {
                $this->page['body'] = $wikka->Action($name . ' ' . preg_replace("/(.+):'(.*)'/U", '$1="$2"', $parameters));
            }
        }
    }
}

if (isset($vars['runtime']) && $vars['runtime'] == 'before') _onpageload($this, $vars);
$this->page['body'] = $this->Format($this->page['body'], 'wakka');
if ((isset($vars['runtime']) && $vars['runtime'] != 'before') || empty($vars['runtime'])) _onpageload($this, $vars);
echo $this->page['body'];


Apparently the first line is required to prevent a hard-to-follow tail chasing event of some sort. It's much too late to figure this out tonight, though. Hence, the simple return. It works for now, but is that good enough? Not if it turns out that every action we want to use in the GlobalActions page must add this line up top! So if you spot the bug, please let me know!

Some examples


{{onpageload uncamel=""}}


This will run the uncamel action with no parameters after the page formatter has been applied.

{{onpageload runtime="before" uncamel=""}}


The same as above, only this time it will be applied before the formatter runs.

{{onpageload runtime="before" customaction1="param1:'value1' param2:'value2'" customaction2=""}}


Executes two actions before processing the page data. The first takes two parameters (it hasn't really been tested, but should work in theory).

One final note, if you would like to apply an action sitewide then you have to create a page called GlobalActions and put the onpageload event there.


Authors


DennyShimkoski


CategoryUserContributions
Comments
Comment by JonasKarlsson
2006-03-05 14:57:22
The instructions say that it works if "if the user has set the 'allow_page_load_actions' config variable to true". How do you do that? Does it require any changes to the code, or does the onpageload action set the variable? I could use some help in getting this to work.
Comment by MyTreo
2006-05-09 15:04:04
JonasKalrsson: I hadn't spotted that and was wondering why it didn't work. You need to add a variable to your wikka.config.php:

"allow_page_load_actions" => true,

This mod seems to crash my Wiki when used with the uncamel action and runtime="before". Any ideas?
Comment by MyTreo
2006-05-20 10:48:26
Update: this mod (or the uncamel mod) caused a memory leak on my Wiki installation. When using {{onpageload uncamel=""}} in my pages when I save an edit, this happens:

PHP Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 40961 bytes) in wikka.php on line 189,

Something to do with the ob_
Comment by 81.76.56.172
2006-05-20 15:12:04
MyTreo, you can try to change the memory allowed per process, either by editing php.ini or by adding a line in your .htaccess - a simple google search for the error message retrieves many results. Take a look at this one for instance: http://forum.mamboserver.com/showthread.php?t=10152&highlight=Allowed+memory+size+8388608+bytes+exhausted
Comment by MyTreo
2006-05-20 18:45:31
Well thanks, I know how to change the memory settings in php.ini but I was thinking that 16MB is a lot of memory to consume on a simple page save operation. Why is it wanting to eat so much memory? 16MB should be ample for all day-to-day operations.

It doesn't seem to be uncamelling anything either, even though the page is saving ok. I'll take another look to double check I made the mods correctly.
Comment by MyTreo
2006-05-21 17:54:51
I checked everything and the code is correct so something in this mod or the uncamel is causing this bad effect on my server. After the memory error it seems to cause the httpd service to fail on the next restart which is corrected with another restart. This is with php 4.3.9. I use ob_ and buffering in a lot of other php apps on the server and never have any problems, and the rest of wikka works perfectly without this mod or without the action in the page.
Comment by RichardMartinNielsen
2008-05-25 20:42:18
I'm ever so slightly baffled. Is ""$this->page"" in the _onpageload code supposed to read ""$wikka->page"" ?
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki