The current mechanism to handle plugin tags is to call each plugin that registered the commonTagsHandler. In turn, each plugin will parse the complete topic text once for each tag it recognizes, even if the tag is not present in the text.
An alternative to this is to scan the text for tags in the form %TAGNAME{}% and call the plugin that knows how to handle them. To do this, the plugin must implements an "accept" method that return true if it recognize the specified tag.
The code is as follows:
my $MAX_RECURSE=4;
sub alternativeApplyHandlers
{
my $plugin;
if( $TWiki::disableAllPlugins ) {
return;
}
$_[0] =~ s/([.\n\r]*?)(%[A-Z]+?({.*?})*?%)/&getPluginRenderedText($1,$2,$_[1],$_[2])/geo; # ($prevText,$tag,$topic,$web)
if ($_[3]<$MAX_RECURSE && $_[0] =~ /%[A-Z]+?({.*?})*?%/) {
alternativeApplyHandlers($_[0],$_[1],$_[2],$_[3]+1);
}
return undef;
}
sub getPluginRenderedText {
# DO NOT UNCOMMENT, use $_[0], $_[1], etc for performance reasons
#($prevText,$tag,$topic,$web) = @_;
my $tag=$_[1];
my $result=$tag;
TWiki::writeDebug("[AlternateApplyHandler] Processing tag = " . $tag) if $debug;
foreach $plugin ( @instPlugins ) {
my $pluginPath = 'TWiki::Plugins::'.$plugin;
my $acceptSub = $pluginPath.'::accepts';
my $processSub = $pluginPath.'::process';
# New Style plugin
if (defined(&$acceptSub) && &$acceptSub($tag)) {
if (defined(&$processSub)) {
# pass topic & web, to allow the plugins authors to reuse commonTagsHandler implementation
$result = &$processSub($tag,$_[2],$_[3]);
last;
} else {
#TWiki::writeWarning("Plugins: Skipping " . $plugin . " , it don't have a process sub defined. ");
}
}
}
return $prevText.$result;
}
Attached to this page is a zipfile with the patch to
PluginsDotPm and an example plugin with a test topic.
--
RafaelAlvarez - 28 Apr 2004
I'm interested to hear what performance impact this actually has. I think to suggest that the plugins "parse" the text is perhaps a little bit generous. Most that I have seen do a RE match on the text and return rapidly if there is no match, so I'm dubious that there's a huge performance advantage. But I can be persuaded!
--
CrawfordCurrie - 28 Apr 2004
- Sounds promising --
MartinCleaver - 29 Apr 2004 - 00:30
- To tell the truth... I didn't found any performance improvement in the test plugin

I'm yet to convert several plugins into this style so I can properly test for performance.
--
RafaelAlvarez - 03 May 2004 - 07:08
there are a few kind of plugins:
- 1) to be executed only when a special tag is present in the topic
- 2) to be executed only when a start and end tag is present ( will only want to see the text between both tags)
- 3) to be always executed
suggestions:
for 1 and 2 the plugins would need to be installed in a directory with the same name as
tag they operate on.
ie: a plugin handling
tag %XYZ% is to be installed in Plugins/XYZ
for plugin handling more than 1 tag, a link (or extra copy) could be created in the relevant directories.
- for 3) no change
- for 2) create one plugin that will handle all the tags and call the relevant plugins with the whole topic text
- for 1) create one plugin that will handle all the starttags/endtags and call the relevant plugins with the only text between the tags (perhaps already split into lines ). What is the proper syntax for starttags - endtags ( %XYZ% - %ENDXYZ% or XYZ - XYZ or ... ).
This would be some kind tag registration at install time. ( instead of execution time as it is now) - has been discussed somewhere else by
ColasNahaboo (link ??). Speed should not decrease with every plugin installed (... well i hope so ).
there are however a few questions i can not answer:
- twiki variables have the same syntax than "plugin call" tags (%XYZ%): are twiki variables (always) expanded before the plugins calls? or is there a need for a new tag ? (
- tags handled by more than 1 plugin: what should be the order of execution ? ( how is it done now ? )
--
MarcelTrap - 30 Jul 2004
Note that if
LocationLocationLocation ever gets merged, this (almost this) can be implemented in 6 lines of code in
FuncDotPm.
--
CrawfordCurrie - 28 Oct 2004
With the changes in the rendering process in
LocationLocationLocation, plugins could register their tags at initialization time, thus not requiring a call to "accepts" on each plugins.
--
RafaelAlvarez - 28 Oct 2004
Raising this /
PluginsRegisteringTheirPlugins for Ed.
--
MartinCleaver - 18 Oct 2005
Actually, this can be already be achieved in Dakar as plugins can register handlers for their tags.
--
RafaelAlvarez - 18 Oct 2005
Marking as done.
--
CrawfordCurrie - 11 Jan 2006