You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Sylvain Wallez <sy...@apache.org> on 2004/12/02 12:13:39 UTC
Re: [RFC] "Cocoon Templates": Name and Tag Interface
Daniel Fagerstrom wrote:
> As you probably have noticed, we are working on a replacement on JXTG.
>
> The goal is that it, as far as it is desirable, should be back
> compatible with JXTG. But instead of being implemented as a huge (and
> somewhat scary) monolith, it will be implemented as a taglib
> framework. By implementing it that way it will be much more open for
> further development and the goal is to implement taglibs similar to
> ESQL etc so that it can work as an XSP replacement as well. It should
> be at least as performant as JXTG.
>
> Jonas has submitted an initial implementation based on the design
> discussions on the list, that Leszek is going to commit.
>
> ---o0o---
>
> We need your input on chosing a name for the framework. And also on
> what data that should be available for the taglibs and in what way the
> tags should be given access to this data. The design of the tag
> "interface" will be an important question for you when you are going
> to implement tags in the future. And it would also be good if we could
> agree about the main direction of the tag design quite soon, so that
> we can start the development of taglibs in parallel with the framework
> development. Please spend some brain cycles on this.
>
>
> Naming
> ======
>
> The goal is that the new template framework should replace JXTG and
> XSP as the "recomended" template system for Cocoon users. It is a
> community effort rather than a one man show. It is based on our
> previous experince of templating solutions.
>
> This should IMO be reflected in the naming. The name should reflect
> the intended purpose rather than being a "brand" name. "JX" in
> JXTemplateGenerator comes from JXPath and as we are going to provide
> support for other expression languages as well, JXTG 2.0 would not be
> a logical name for the framework IMHO.
> I would propose that we (analogous with CForms) refer to it as
> "template" in block name, package name, name spaces and so on. When it
> actually delivers what is promised, we can refer to it as Cocoon
> Template or CTemplate.
>
> To show that we care about our users previous investments in Cocoon
> technology, we can say that JXTG has been re-implemented as a Cocoon
> Template tag lib.
>
> Of course other and better naming sugestions are most welcome.
>
>
> Tag "Interface"
> ===============
>
> What data should be available for the taglib writer and how should it
> be made accessible? What about thread safety?
>
> Expressions
> -----------
>
> This is somewhat OT in the current context but IMO expressions, (the
> stuff inside ${}), should only have access to FOM and preferably just
> read access. IMHO expressions should not have side effects.
FOM sounds ok, or at least some "cocoon" object giving access to flow
view data (if any, as it can be used outside of flowscript), request,
session, etc.
Expressions should have no side effects although this is difficult to
enforce strictly as the EL must be able to call a method and we cannot
control what happens within the method.
> What Data in Tags?
> ------------------
>
> A tag need access to:
>
> * FOM
> * The current XMLConsumer for output
> * The content of its attributes
> * The content of its body (the possibility of executing the body and
> geting the result)
+1 The two last items are especially important to implement the CForms
template language (see jx-macros.xml).
> The following data is also useful for some tag libs:
>
> * A variable stack for handling local variables in tags or macros
> * The tag repository
> * The source resolver
That's not needed, as it can be looked up in the ServiceManager.
> * The component manager (e.g. for geting a DB connection)
> * Its parent tag
> * The content of its body (the possiblity to get the body unevaluated)
+1
> IMHO tags should behave as if they are side effect free. Side efects
> should be performed in flowscripts. From this we can infer that we
> only should have read access to the above data. But in practice it
> might be hard to enforce and furthermore even if the tag behave as it
> is side effect free, it might be better (or the only possiblity) to
> implement it in terms of side effects.
>
> Implementation details are discussed in the section "Adding Executable
> Tags" in
> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=110132582421156&w=2.
>
> Have I forgotten something or should we remove something?
>
> How to Make Data Accessible in Tags
> -----------------------------------
>
> There are two main type of events in the life cycle of a tag: setup
> and execution. For a thread safe tag, the setup phase can be divided
> in: script compile time setup and execution time setup.
>
> The relation between the tag and the framework has many parallels with
> the relation between a component and a component manager, so similar
> solutions are possible.
>
> We can have reflection based solution with setter injection of
> attributes and possibly the rest of data also. We can have interface
> driven injection, (Avalon framework style), where the tag implements
> various interfaces for geting the various input data types.
>
> We can also have more "static" solutions where the tag has to
> implement a certain interface and get all the data with methods in the
> interface or in one large context object.
>
> Reflection based methods are more flexible, but should probably only
> be performed during script compile time setup, due to keep good
> performance.
>
> See the above reference for examples and more details.
>
> Thread Safe or Not?
> -------------------
>
> Thread safe tags can have better performance as more work can be done
> during script compile time, but they might be harder to write. What
> should we chose or should we support both types?
I don't see how we can possibly cache precompiled templates if some tag
instances are not threadsafe. So IMO *all* tags should be threadsafe.
If we make the parallel with the TreeProcessor, tags should receive
something similar to InvokeContext. This is an object that holds all
execution-time data such as the generator's <map:parameter>, the object
model (or maybe not as it's available through the Context) and the
variable stack.
For some tags to be able to store execution-time data, the invocation
object should also be able to hold some arbitrary attributes, possibly
associated to the tag instance itself. That provides support for both
tag-related data (e.g. some data created on start that is needed on end
such as SQL connections) or inter-tag communication such as <ft:class>
definitions later used by <ft:new> tags.
Something like:
void setAttribute(String name, Object value);
Object getAttribute(String name);
void setTagAtttribute(Tag tag, String name, Object value);
Object getTagAttribute(Tag tag, String name);
Sylvain
--
Sylvain Wallez Anyware Technologies
http://www.apache.org/~sylvain http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: [RFC] "Cocoon Templates": Name and Tag Interface
Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Sylvain Wallez wrote:
> Daniel Fagerstrom wrote:
>
>> Sylvain Wallez wrote:
>>
>>> Daniel Fagerstrom wrote:
>>
<snip/>
>> You are refering to the source resolver i guess? Maybe the tag
>> repository should be controlled by ServiceManager as well so that
>> included and compiled taglibs are inherited to subsitemaps?
>
> Yes, taglibs should be standard components declared in the service
> manager. That way, they are automatically inherited in subsitemaps.
> What we need also is a "standard" set of taglibs that are declared in
> the top-level service manager, i.e. cocoon.xconf.
Sounds good.
> Now about the SourceResolver, it's available in the ServiceManager
> using lookup(SourceResolver.ROLE). So it doesn't need to be passed
> explicitely as part of the runtime setup.
>
> The fact that generator.setup() has a SourceResolver parameter is
> historical, at a time where it wasn't available through the service
> manager.
Didn't know that.
<snip/>
>> You can put a threadsafe tag factory together with the class name of
>> the thread unsafe tag and possibly other compile time datainto the
>> script. Then the thread unsafe tag is created and instantiated at
>> runtime. Jelly work like that, its certainly has some runtime costs,
>> but it is easier to write the tags.
>
> Mmmh...
>
> You then achieve something similar to the CForms architecture where a
> form definition is translated into a cached, immutable and threadsafe
> FormDefinition object, which acts as a factory for actual Widgets.
>
> This behaviour is needed for CForms as every widget intrinsically have
> to hold some state information and therefore are specific to a
> particular usage of the form, and that state must persist across
> request/response cycles.
>
> Do we need the same for tags? I'm not sure.
Don't think we need it either. I'll try to implement a number of tags
and see what I think.
> Thinking further, we don't even need the per-tag attributes I
> mentioned below, as a tag implementation will drive the execution of
> its children.
>
> Practically, this means that a Tag should have a single "execute"
> method invoked at generation-time, that will do its job and invoke its
> children as part of this job. Any tag-related state can then be
> represented as local variables.
Sounds good.
/Daniel
Re: [RFC] "Cocoon Templates": Name and Tag Interface
Posted by Sylvain Wallez <sy...@apache.org>.
Daniel Fagerstrom wrote:
> Sylvain Wallez wrote:
>
>> Daniel Fagerstrom wrote:
>
>
> <snip/>
>
>>> What Data in Tags?
>>> ------------------
>>>
>>> A tag need access to:
>>>
>>> * FOM
>>> * The current XMLConsumer for output
>>> * The content of its attributes
>>> * The content of its body (the possibility of executing the body and
>>> geting the result)
>>
>>
>> +1 The two last items are especially important to implement the
>> CForms template language (see jx-macros.xml).
>>
>>> The following data is also useful for some tag libs:
>>>
>>> * A variable stack for handling local variables in tags or macros
>>> * The tag repository
>>> * The source resolver
>>
>>
>> That's not needed, as it can be looked up in the ServiceManager.
>
>
> You are refering to the source resolver i guess? Maybe the tag
> repository should be controlled by ServiceManager as well so that
> included and compiled taglibs are inherited to subsitemaps?
Yes, taglibs should be standard components declared in the service
manager. That way, they are automatically inherited in subsitemaps. What
we need also is a "standard" set of taglibs that are declared in the
top-level service manager, i.e. cocoon.xconf.
Now about the SourceResolver, it's available in the ServiceManager using
lookup(SourceResolver.ROLE). So it doesn't need to be passed explicitely
as part of the runtime setup.
The fact that generator.setup() has a SourceResolver parameter is
historical, at a time where it wasn't available through the service manager.
>>> Thread Safe or Not?
>>> -------------------
>>>
>>> Thread safe tags can have better performance as more work can be
>>> done during script compile time, but they might be harder to write.
>>> What should we chose or should we support both types?
>>
>>
>> I don't see how we can possibly cache precompiled templates if some
>> tag instances are not threadsafe. So IMO *all* tags should be
>> threadsafe.
>
>
> You can put a threadsafe tag factory together with the class name of
> the thread unsafe tag and possibly other compile time datainto the
> script. Then the thread unsafe tag is created and instantiated at
> runtime. Jelly work like that, its certainly has some runtime costs,
> but it is easier to write the tags.
Mmmh...
You then achieve something similar to the CForms architecture where a
form definition is translated into a cached, immutable and threadsafe
FormDefinition object, which acts as a factory for actual Widgets.
This behaviour is needed for CForms as every widget intrinsically have
to hold some state information and therefore are specific to a
particular usage of the form, and that state must persist across
request/response cycles.
Do we need the same for tags? I'm not sure. Thinking further, we don't
even need the per-tag attributes I mentioned below, as a tag
implementation will drive the execution of its children.
Practically, this means that a Tag should have a single "execute" method
invoked at generation-time, that will do its job and invoke its children
as part of this job. Any tag-related state can then be represented as
local variables.
<snip/>
Sylvain
--
Sylvain Wallez Anyware Technologies
http://www.apache.org/~sylvain http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: [RFC] "Cocoon Templates": Name and Tag Interface
Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Sylvain Wallez wrote:
> Daniel Fagerstrom wrote:
<snip/>
>> What Data in Tags?
>> ------------------
>>
>> A tag need access to:
>>
>> * FOM
>> * The current XMLConsumer for output
>> * The content of its attributes
>> * The content of its body (the possibility of executing the body and
>> geting the result)
>
> +1 The two last items are especially important to implement the CForms
> template language (see jx-macros.xml).
>
>> The following data is also useful for some tag libs:
>>
>> * A variable stack for handling local variables in tags or macros
>> * The tag repository
>> * The source resolver
>
> That's not needed, as it can be looked up in the ServiceManager.
You are refering to the source resolver i guess? Maybe the tag
repository should be controlled by ServiceManager as well so that
included and compiled taglibs are inherited to subsitemaps?
>> Thread Safe or Not?
>> -------------------
>>
>> Thread safe tags can have better performance as more work can be done
>> during script compile time, but they might be harder to write. What
>> should we chose or should we support both types?
>
>
>
> I don't see how we can possibly cache precompiled templates if some
> tag instances are not threadsafe. So IMO *all* tags should be threadsafe.
You can put a threadsafe tag factory together with the class name of the
thread unsafe tag and possibly other compile time datainto the script.
Then the thread unsafe tag is created and instantiated at runtime. Jelly
work like that, its certainly has some runtime costs, but it is easier
to write the tags.
Anyway, I agree with you. We start by requireing the tags to be thread
safe and implement the core tag libraries that way. Then we can
implement "tag adapters" for other tag life styles later if we feel that
it is needed.
> If we make the parallel with the TreeProcessor, tags should receive
> something similar to InvokeContext. This is an object that holds all
> execution-time data such as the generator's <map:parameter>, the
> object model (or maybe not as it's available through the Context) and
> the variable stack.
Sounds good, we have one "CompileContext" and one InvokeContext.
> For some tags to be able to store execution-time data, the invocation
> object should also be able to hold some arbitrary attributes, possibly
> associated to the tag instance itself. That provides support for both
> tag-related data (e.g. some data created on start that is needed on
> end such as SQL connections) or inter-tag communication such as
> <ft:class> definitions later used by <ft:new> tags.
>
> Something like:
> void setAttribute(String name, Object value);
> Object getAttribute(String name);
> void setTagAtttribute(Tag tag, String name, Object value);
> Object getTagAttribute(Tag tag, String name);
I had some vauge idea about putting such info in the variable stack. But
it might be better to sstore such info so that it is invisible for the EL.
Thanks for your comments!
/Daniel