I am developing a syntax plugin that has an increment each time a matching tag is found. In trying to do as much processing in the handle routine as preferred, I discovered that the handle function was being called twice when the cache is being built. This had the effect of starting the increment on the published page at twice the number of calls. This behaviour exists in 2006-10-06 and the latest snapshot 2007-02-27. To show this behaviour I have created this simple plugin which includes a backtrace:
<?php
/**
* Plugin Now: Inserts a timestamp.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Christopher Smith <
chris@jalakai.co.uk>
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_handletest extends DokuWiki_Syntax_Plugin {
var $_counter = 0;
function getInfo(){
return array(
'author' => 'me',
'email' => '
me@someplace.com',
'date' => '2005-07-28',
'name' => 'Now Plugin',
'desc' => 'Include the current date and time',
'url' => 'http://wiki.splitbrain.org/plugin:tutorial',
);
}
function getType() { return 'substition'; }
function getSort() { return 32; }
function connectTo($mode) { $this->Lexer->addSpecialPattern('[TEST]',$mode,'plugin_handletest'); }
function handle($match, $state, $pos, &$handler){
$this->_counter += 1;
print '<pre>counter='.$this->_counter."nmatch=$matchnstate=$statenpos=$pos</pre>";
print '<pre>'.$this->_debug_reverse_backtrace().'</pre>';
return "Counter=".$this->_counter;
}
function render($mode, &$renderer, $data) {
if($mode == 'xhtml'){
$renderer->doc .= $data;
return true;
}
return false;
}
function _debug_reverse_backtrace()
{
// Get backtrace
$backtrace = debug_backtrace();
// Unset call to debug_print_backtrace
array_shift($backtrace);
// Iterate backtrace
$calls = array();
$depth = count($backtrace) - 1;
foreach ($backtrace as $i => $call) {
$location = $call['file'] . ':' . $call['line'];
$function = (isset($call['class'])) ?
$call['class'] . '.' . $call['function'] :
$call['function'];
$params = '';
if (isset($call['args'])) {
$params = implode(', ', $call['args']);
}
$calls[$depth - $i] = sprintf('^%s(%s) called at [%s]',
$function,
str_replace("n", 'n', $params),
$location);
}
ksort($calls);
return implode("n", $calls);
}
}
To test it create a page containing one or more [TEST] tags and call it with the purge=true option in the url.
On my system I have merged the two traces into the following:
==COMMON==
^act_dispatch(show) called at [d:wwwdokuwikidoku.php:75]
^include(d:wwwdokuwikilibtpldefaultmain.php) called at [d:wwwdokuwikiincactions.php:126]
^tpl_content() called at [d:wwwdokuwikilibtpldefaultmain.php:91]
^trigger_event(TPL_ACT_RENDER, show, tpl_content_core) called at [d:wwwdokuwikiinctemplate.php:45]
^doku_event.trigger(tpl_content_core, 1) called at [d:wwwdokuwikiincevents.php:197]
^tpl_content_core(show) called at [d:wwwdokuwikiincevents.php:91]
^html_show() called at [d:wwwdokuwikiinctemplate.php:62]
^p_wiki_xhtml(handle_test, , 1) called at [d:wwwdokuwikiinchtml.php:278]
^p_cached_output(d:wwwdokuwikidatapages/handle_test.txt, xhtml, handle_test) called at [d:wwwdokuwikiincparserutils.php:42]
===CALL 1===
1. ^cache_renderer.usecache() called at [d:wwwdokuwikiincparserutils.php:149]
1. ^p_set_metadata(handle_test, Array, 1) called at [d:wwwdokuwikiinccache.php:211]
1. ^p_render_metadata(handle_test, Array) called at [d:wwwdokuwikiincparserutils.php:270]
1. ^p_cached_instructions(d:wwwdokuwikidatapages/handle_test.txt, , handle_test) called at [d:wwwdokuwikiincparserutils.php:383]
===CALL 2===
2. ^p_cached_instructions(d:wwwdokuwikidatapages/handle_test.txt, , handle_test) called at [d:wwwdokuwikiincparserutils.php:153]
===COMMON===
^p_get_instructions([TEST]n) called at [d:wwwdokuwikiincparserutils.php:183]
^doku_parser.parse([TEST]n) called at [d:wwwdokuwikiincparserutils.php:214]
^doku_lexer.parse(n[TEST]nn) called at [d:wwwdokuwikiincparserparser.php:117]
^doku_lexer._dispatchtokens(, [TEST], _plugin_handletest, 1, 1) called at [d:wwwdokuwikiincparserlexer.php:399]
^doku_lexer._invokeparser([TEST], 5, 1) called at [d:wwwdokuwikiincparserlexer.php:440]
^doku_handler.plugin([TEST], 5, 1, handletest) called at [d:wwwdokuwikiincparserlexer.php:511]
^syntax_plugin_handletest.handle([TEST], 5, 1, Object) called at [d:wwwdokuwikiincparserhandler.php:76]