create new tag
, view all tags
The line-by-line plugins handlers outsidePreHandler and insidePreHandler are called on each line processed by the core rendering loop. This:
  1. Is very expensive, as these functions are called on every line. Even if they are not implemented there is a cost to the rendering loop in finding that out.
  2. Is inconsistent, as there are no equivalents for any other block types such as <verbatim>
    • Actually it is for PRE and VERBATIM, the two only blocks where TWikiML to HTML rendering needs to be turned off -- PTh
    • No, there is no insideVerbatimHandler, so it's inconsistent.
  3. Prevents optimisation of the core rendering loop, by requiring line-by-line processing of all TWiki ML
A second problem is the inconsistencies surrounding the startRenderingHandler. This handler is called on the entire text, which is good, but after verbatim blocks have been replaced with placeholders, which is bad. Who is to say a plugin doesn't need these blocks (and indeed I do, which is where this all started).

The proposals are (separated so they can be referred to in discussion)

  1. DEPRECATE outsidePreHandler in the DakarRelease and REMOVE from FreetownRelease
  2. DEPRECATE insidePreHandler in the DakarRelease and REMOVE from FreetownRelease
  3. DEPRECATE startRenderingHandler in the DakarRelease and REMOVE from FreetownRelease
  4. IMPLEMENT preRenderingHandler to the following spec: sub preRenderingHandler( \$text, \%removed ) where \$text is a reference to the text with the head, verbatim and pre blocks replaced with placeholders, and \%removed is a reference to a hash that maps the (strongly typed) placeholders in the text to the removed blocks e.g. $removed->{"head"}, $removed->{"verbatim5"}, $removed->{"pre2"}.
  5. DEPRECATE endRenderingHandler in the DakarRelease and REMOVE from FreetownRelease
  6. IMPLEMENT postRenderingHandler to the following spec: sub postRenderingHandler( $text )
. I believe this revised spec gives maximum flexibility both to the core, but also far more flexibility to the plugin author. There is no compromise on functionality, and any existing outsidePreHandler can easily be implemented in terms of preRenderingHandler.

See PluginsConformanceReport for a breakdown of the plugins that call the handlers proposed for deprecating; but note that several of these plugins don't work on Cairo, or simply implement stubs for these handlers.

-- CrawfordCurrie - 23 Feb 2005

That needs to be looked at very carefully. A Plugin API should be enhanced, also with better functions that replace existing functions. But deprecated functions should not be deleted or we could not call it a Plugin API.

-- PeterThoeny - 01 Mar 2005

Crawford, you say that any outsidePreHandler can easily be implemented in terms of preRenderingHandler. Can you give instructions on how to do this (I assume there is a reason why these authors used outsidePreHandler). Note that there are some widely used plugins that rely on outsidePreHandler.

-- ThomasWeigert - 01 Mar 2005

As I understand, the preRenderingHandler will have similar content to what you see in the outsidePreHandler, including the placeholders for the removed verbatim tags, but containing all text, not just one line. The outsidePreHandler was introduced historically so that line operations could be done easily on "renderable text" (is that a word?), e.g. not worring about text inside PRE or VERBATIM tags.

With the preRenderingHandler you get the whole text and the Plugin needs to do line by line processing if so needed. This is much better performance-wise.

So, I think Crawford's proposed change proposal is a very good one, up to the point of deleting deprecated functions.

-- PeterThoeny - 01 Mar 2005

Thomas, as Peter says the outsidePreHandler is a callback on each line outside a pre block. Since the preRenderingHandler would provide the text with pre and verbatim separated out, the existing outsidePreHandler could be implemented as an interation over the lines in the \$text parameter.

Peter, yes, you've got the idea. The reason for wanting to delete is a simple one; efficiency. The code can be written to be a lot more efficient if the *sidePreHandler is removed. However, since it is clearly easy for a plugin to implement *sidePreHandler in terms of preRenderingHandler, it is also easy for the core code to do the same. i.e. if any plugin declares one of these handlers, then activate a loop that executes the line loop, so if deletion is not an option, they can be retained.

Note that it is generally a very bad idea to try to maintain too much legacy in any API. I accept that EdinburghRelease may be too soon to remove these functions, but there needs to be a plan for when they can be removed (FreetownRelease)

-- CrawfordCurrie - 01 Mar 2005

This is implemented now, r3723, spec of the new handlers as follows:

preRenderingHandler( $text, \%map )

  • \$text - a reference to the text, with the head, verbatim and pre blocks replaced with placeholders
  • \%removed - reference to a hash that maps the placeholders to the removed blocks.

Handler called immediately before TWiki syntax structures (such as lists) are processed, but

Placeholders are text strings constructed using the tag name and a sequence number e.g. "pre1", "verbatim6", "head1" etc. Placeholders are inserted into the text inside <!--!marker!--> characters so the text will contain <!--!pre1!--> for placeholder pre1.

Each removed block is represented by the block text and the parameters passed to the tag (usually empty) e.g. for

<pre class="slobadob">
the map will contain:
$removed->{"pre1"}{text}:   XYZ
$removed->{"pre1"}{params}: class="slobadob"
Iterating over blocks for a single tag type is easy. For example, to prepend a line number to every line of every pre block you might use this code:
foreach my $placeholder ( keys %$map ) {
    if( $placeholder =~ /^pre/i ) {
       my $n = 1;
       $map->{$placeholder}{text} =~ s/^/$n++/gem;
Since TWiki::Plugins::VERSION = '1.026'

postRenderingHandler( $text )

  • \$text - a reference to the entire rendered HTML page (not including HTTP headers). May be modified in place.

You will note the difference in the postRenderingHandler; it just seemed more logical that way.

Note that there is an impact of this change on the way JavaScript can be handled. It would be easy to add a takeOutBlocks for script sections, thus allowing JavaScript to be embedded in topics.

Another impact of the change is that it allows the TestFixturePlugin to be much smarter.

With the deprecation of the PRE handlers I have been able to restructure the rendering loop so that most subsitutions are now done on a single pass through the text. This may result in unexpected behaviours, so please be alert. The tests all pass, but since I wrote all the tests that hardly says very much! wink

-- CrawfordCurrie - 03 Mar 2005

Crawford, while you were at it, did you look at how we could augment these handlers so that Plugins can add javascript in a consistent and straightforward manner?

-- ThomasWeigert - 04 Mar 2005

No. I think this is a bigger topic (the "consistent, straighforward" bit anyway).

However you will note that as well as PRE and verbatim sections I have also parsed and passed the HEAD to the plugin, so in theory anyway a plugin can simply add a script section to the header. That would be my own chosen approach e.g. to add JSCalendar or style sheets.

Note that getRenderedVersion is called several times during rendering, on different texts, so you:

  • can't assume there will be a HEAD for every call,
  • should be able to guarantee that at least one call has a HEAD block with it (as long as your templates are sensible)
  • can't guarantee that the call with the HEAD is the last call (in fact it probably won't be, as the template is rendered before the text within it).

-- CrawfordCurrie - 04 Mar 2005

Thanks. The last point probably will be an issue, as sometimes the plugin may collect up js pieces and wants to finally insert it into the head section. But if that section is already gone, then we are out of luck. I ran into this last year once but don't remember the details....

-- ThomasWeigert - 04 Mar 2005

Aye, that's why I mentioned it. I tried to think of a solution while I was working through the code, but nothing obvious sprang to mind other than yet another handler ( pageReadyHandler ) which has other impacts.

-- CrawfordCurrie - 05 Mar 2005

Is the reason for deprecating the endRenderingHandler that there is no value having this plugin between inserting the pre and verbatim blocks? Note that there is one difference that seems important to postRenderingHandler in that head and doctype have already been applied before the latter.

-- ThomasWeigert - 14 May 2005

Correct. postRenderingHandler lets you handle the entire rendered HTML page, rather than just a subset.

-- CrawfordCurrie - 14 May 2005

Edit | Attach | Watch | Print version | History: r13 < r12 < r11 < r10 < r9 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r13 - 2007-01-09 - PeterThoeny
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.