On 3/25/07, Sergiu Dumitriu <sergiu.dumitriu@gmail.com > wrote:


On 3/22/07, Vincent Massol < vincent@massol.net> wrote:
Hi,

After long thoughts where I my opinion swinged in one direction and
then in another and then back again, I think Sergiu and Catalin are
right. I won't send the 5 emails that I started writing explaining
the pros and cons of each approach. Instead, to summarize:

* I like the idea that a Skin is made of a Skin object (defining a
general layout and only extension points (no content)) and of
SkinElement objects (implementing the extension points). I like it
because it allows any user to easily modify only a specific part of
the skin by either editing the related page or by providing an
implementation of that extension point in a separate page.

* I like the idea of having a special Renderer for expanding
expansion points and their implementations. This allows plugging
different Renderers if people want to use a different expansion point
mechanism (like using PHP for defining their extension points and
implementations, using Java API calls, etc).

At which point do we apply this? Velocity/Groovy generates code, and Radeox too, so it will have to be after these. On the other hand, the extension depends on the context, so it should be executed before the velocity/groovy/radeox renderers.


OK, I think I found something which brings us closer to achieving this.

The only way to incrementally add extensions and extension points, without continuously reparsing the rendered content, is to use a SAX-based parser (let's call it EP-parser) on the input and output streams for the renderers, which checks whenever a new tag is introduced if it corresponds to an EP. If it does, then instead of sending the next characters from the original input to be processed, it sends the code of the extension point.

However, there is an issue here, with the context. For example, consider the following (pseudo)script:

#foreach($i in $xwiki.searchDocuments($someQuery))
#set($qdoc = $xwiki.getDocument($i))
#set($qobj = $qdoc.getObject("Some.Class"))
<span class="EP-class">qobj.display("desc")</span>
#end

...and an extension which needs the $qobj variable. If the velocity parser uses a buffer, then the SAX-parser will only receive the full list of spans, with the $qobj variable set to the last value. We need to see if Velocity can be forced (or already does) not to use buffers. Then, if the EP-parser and Velocity share the context/vcontext, and if we can stop the current velocity rendering thread after each EP-trigger, we might have a solution (at least for the velocity rendering).

We need to see how we can mix the different renderers, so that the velocity context is still available after expanding a radeox macro or filter.

Also, we need to consider the WEM (Wiki Event Model) from WikiModel as a possible starting point for the EP-parser. I really have to find some time to take a deeper look at WM.

Does anybody see some holes in this solution? Can we start filling in the Ideas page on xwiki.org?

Thanks,
Sergiu
--
http://purl.org/net/sergiu