Daniel Fagerstrom wrote:
Stefano Mazzocchi wrote:
<snip reason="agree"/>

5) control should be inverted: the template must be a view, it should be 'pushed' the data in, it should not contain any data-pulling logic other than the one used to pull data from the dataset passed on by the underlying controlling stage.


Here I agree even more ;) The choice of data to push into the template should be performed in the sitemap or in the flowscripts. Furthermore I think that generators and transformers should be free from side effects.

I agree, but it's going to be hard to enforce this. It might come up as a general 'design pattern' later on, when enough common knowledge is gained, collected and distilled.


But I think that would take years.

Ideally, IMO, generators can read data that is pushed from the environment by the control mechanism, (sitemap and flowscripts). Transformers just transforms input to output and has no connection to the environment, (this is probably overly restrictive in practice). Serializers can push data into the environment, see [1] for my view on this. The data can then be manipulated in whatever procedural way by the flowscripts.

...


- o -

IMHO, the template language which is closer to the optimum is XSLT


Wow!!! :)

We decided to follow that path at the company that I work for a little bit more than two years ago and have (at least most of the time) been happy with that. We are basically using XSLT as a generator as well and use an extended version of the TraxTransformer makes a larger part of the object model available as parameters. We have written a number of webapps in this way. No doubt, we have found and used a couple of anti patterns :/ during this work, but most of the time it has worked well and beeen productive.

Great. good to have real-life experience to get back on the ground :)


but only with one change:

FORGET THE XML SYNTAX!


I tend to agree, after having refactored a number of XSLT intense webapps written booth by myself and by other people, I have been forced to the conclusion: it is fairly easy to write XSLT (when you are used to it), but it migth be a hell to grasp what it does when you read it.

Yep.


I'm entering wild mode now, so bear with me. Suppose you had:

 1) a syntax that is simple and efficient to describe a stylesheet
 2) a defined object model accessible thru regular xpath queries
 3) no ability to call extensions


Let me give you an example of what I mean. First of all, let us assume that the template engine assumes an xml-izable representation of all the data it has access to.


So, for example:

input:
<list name="whatever" xmlns:ns="http://whatever/";>
 <item xml:lang="en">blah</item>
 <item xml:lang="it">blah</item>
 <item>
  <ns:subitem>blah</ns:subitem>
  <ns:subitem>blah</ns:subitem>
 </item>
</list>


Dare I hope that "input:" refers to the inputstream? :P It could also be usefull with multipartinput: (see [2,3]).

It could, but this reminds me of forking pipelines and I don't get a nice impression out of this.


i think it should be the underlying controlling logic to drive what 'part' of the input stream (consider it multiparted) should be elaborated.

it is trivial to add a 'part selection' capability to the StreamGenerator.

request:
...

session:
...

deli:
...

flow:
...

<snip>code example</snip>

Your syntax looks quite good and is fairly simmilar to XQuery, (see the examples in [4], e.g.). XQuery has been described as "XQuery = XSLT - templateRules - nonAbbreviatedXPathAxes" [5], this might not be the whole truth, but from a syntax point of view I think that:

XQuery + templateRules + nonAbbreviatedXPathAxes - XPath2 specific stuff

could be a good syntax. If XQuery gains popularity we would get editor support for and (partial) language descriptions for free.

Good point, XQuery makes a good candidate for a starting point.


"request::lang" etc, could be translated to the the XSLT function "document(request:/lang)", where "request:" is a Source. With the new Source and XSLTProcessor implementations from excalibur we get cashing for free if the parameter to the document function is determinable at compile time.

oh, yes, I thought about that too, but, gosh, I hate document() so much. What about XSLT extensions?


We would thus need to write (xml-)sources for all parts in the object model, and for other kinds of data that we would like to use our the template language. This could easliy be done with e.g. domify.sf.net, that was mentioned at xml-apache-general today, [6]. To make cashing depend on more specific and to gain efficency for large input data structures, one could implement xpointer functionality for some of the sources:

document(hugedb:/foo#xpointer(//bar[3]))/foo.

overkill. if you have such a complex dataset, you should be having a business logic in java that prepares the data beans for your view anyway.


the above should be parsed, transformed into a regular xslt stylesheet and fed into a normal XSLT processor with extensions.


One could prototype the idea by using the Chaperon transformer and the cocoon protocol for transforming the src-input to the TraxTransformer.

Ah, you're right! Chaperon itself does it for its own xml-ized syntax. Didn't think about that. I think it can be much more than a prototype.


The above will then be:

1) useful for both generation and transformation (the input object will be empty and the / template would be called)


We normaly use the pattern:

<map:match pattern="foo.html">
  <map:generate src="empty.xml"/>
  <map:transform src="foo.xsl"/>
  <map:serialize/>
<map:match/>

(where empty.xml contains "<empty/>"), for using XSLT as a generator,

Talking about hacks :)


but it would probalbly be a good idea to write a TraxGenerator. This way we could also make different parts of the environment availabe in the TraxGenerator and the TraxTransformer (if this is desired).

Yes, much nicer (and faster, I suspect) than the above hack.



Side effects ============

I cannot help but throwing in some wild RTs:

go right ahead. I like mindbombs :)


We need an TraxSerializer as well ;)

oh dear.


As discussed earlier [7], I belive that the basic processing cycle for webapps should be as follows:

1. The flowscript call the sitemap for generating a page that is send to the browser (output pipeline).
2. The flowscript call the sitemap for taking care of the posted input from the browser (input pipeline).
3. The flowscript processes the data from the input pipeline and migth call business logic.


The task of the input pipeline is to gather and possibly change format of the input and to store the (xml)-data in some object model objects that therafter can be further processed by the flowscript. An example of such an object could be the form model for form handling.

I was thinking about this the other day: there is no way for the flowscript to call the sitemap and get something *out* of it. What I ended up doing is to serialize the output of the serializer on disk and then read it again.


Admittedly hacky.

But I didn't have time to think deeper about it. For sure, there is lack of simmetry when a pipeline is used 'detached' from the normal servlet input/output streams.

A way to achive this would be to package the parts of the object model that we want the pipeline to be able to modify as ModifiableSource. The modifiable sources should only be available in the TraxSerializer and that would enforce that the template generator and transformer are side effect free. The serializer template could then do things like:

<xsl:result-document href="formdata:/úserdata">
  <user>
    <name><xsl:value-of select="name"/></name>
    ...
  </user>
</xsl:result-document>

agggggghhhhhhhh, forking pipelines again!!! :-)


No, seriously, I think there is value in giving the serializer the ability to access the object model, both for reading and for writing, but having serveral side effects... hmmm, that would also require a pretty good knowledge of the DOM-like shape of all the objects given to the stylesheet which might be kind of hard.

Unfortunately xsl:result-document is only a part of XSLT2.0. There is
a corresponding tag exsl:document in EXSLT [8]. Most XLST implementaions has propetary extensions for multiple output documents, but those in Xalan and XSLTC seem to asume that the output should be a file.

ok


Saxon seem however to have a construction that use a source resolver.

but we would then need to reparse those streams to regain the data and remarshall it to the data objects. I see your point and I think it could be pretty powerful from a usability perspective (compared to write your own serializers that do objectmodel writes directly) but I'm not sure we really need that complexity right now.


2) compilable

3) stream based

4) reduced verbosity yet terse

5) access to all cocoon object model and extensible

6) namespace-capable

7) declarative

What do you think?


I think it is an excelent proposal, an XSLT based template language with XML access to the object model would replace a large part of the existing tag languages within Cocoon, it would also replace quite a few generators and transformers. It would also make it easier to learn Cocoon for new users and Cocoon would be percieved as much more coherent.
>
There are a some template languages where I don't see a natural fit to XSLT: ESQL or the SQLTransformer. The chart transformer from Fins have xml input and output and is side effect free and could (at least in principle) have been implemented in XSLT. It is however (for good reasons ;) ) implemented in Java instead by using JFreechart. The mentioned examples could be implemented as extension tags in XSLT, but as long as the interfaces for extension tags not are standardized that would be a maintainance nightmare. I would also open up for all kind of abuses. So I don't think that XSLT could replace all template langages that are used in Cocoon, but still a large share of them.

We'll see.


-- o --

To continue we need to define a syntax and a translation scheeme to XSLT for the new template language so that we can write a parser. We also need to define the XML-view and thew url-space for the object model so that we can start to write sources.

Hold on, let's try to apply some SoC:


first concern: non-xml syntax
-----------------------------

1) it should reduce verbosity to a minimum, yet be terse enough not to result cryptic.

2) it should reuse standard syntaxes (xpath, xquery) as much as possible (reduce wheel reinvention to a bare minimum)

3) it should be only syntax sugar on top of XSLT (with eventually some extensions) so that it can be automatically translated to XSLT.


second concern: access to the object model ------------------------------------------

1) it should allow access read access to the cocoon object model in an efficient way.


third concern: use of XSLT for generation -----------------------------------------

 1) it should allow the use of literal result elements stylesheets
    [http://www.w3.org/TR/xslt#result-element-stylesheet] as templates
    for a generator

The three concerns are fully isolated and can be independently implemented/designed.

I think the most important one is the access to the object model, followed by the use of XSLT for generators and then, at the end, come up with a better syntax.

I'm personally more oriented to see the object model accessed thru the use of xslt extensions than thru the use of the document() function. But this yields the problem of lack of portability between extensions which I know nothing about.

The separation into layers also allows people who don't see nothing wrong in the xml xslt syntax to keep using it without worries.

the use of chaperon will result in something like this

 <map:match pattern="*.xttl">
    <map:generate src="{1}.xttl"/>
    <map:transform src="stylesheets/mathexp.xsl"/>
    <map:transform type="lexer" src="grammars/xttl.xlex"/>
    <map:transform type="parser" src="grammars/xttl.xgrm"/>
    <map:transform src="stylesheets/xttl2xslt.xsl"/>
    <map:serialize type="xml"/>
 </map:match>

then do

 <map:match ...>
  <map:generate src="...">
  <map:transform type="xslt" src="cocoon:/mytemplate.xttl"/>
  ...
 </map:match>

or

 <map:match ...>
  <map:generate type="xslt" src="cocoon:/mytemplate.xttl">
  <map:transform .../>
  ...
 </map:match>

XTTL stands for eXtensible Transformation and Template Language so we finally get rid of that useless "style" concept for transformations which should only belong to CSS.

When do we start? ;)

I would suggest waiting for after we release 2.1


Stefano.




Reply via email to