On 3/25/07, Sergiu Dumitriu <sergiu.dumitriu(a)gmail.com> wrote:
 On 3/22/07, Vincent Massol < vincent(a)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