Daniel Fagerstrom wrote:

Stefano Mazzocchi wrote:

All I ask from a template language:

1) something that HTML designers can edit with Dreamweaver
2) something that doesn't use namespaced tags to identify dynamic scopes (clashes with #1)
3) something that doesn't use the name taglib


That's pretty much all you have to do to make me happy.


Dreamweaver friendly means basically that it should be attribute driven I guess?

Any prohibition on (non-HTML) namespaced tags would imply to me that arbitrary namespaced attributes would be a no-no in Dreamweaver as well. Stefano, as I haven't ever used Dreamweaver for more than ten minutes, is this limitation a rendering issue or data entry issue? I question the position though. Taking two obvious possibilites:


1. Velocity syntax: just plugs in in the best-case scenario as text but suffers from the danger of having the text "#foreach" wrapped in a tag by the editor. Well-formedness is not guaranteed. (I think. Correct em if I'm wrong.)

2. Namespaced tag or attribute: may not be compatible with Dreamweaver (strikes me as a serious limitation that needs to be addressed by the Dreamweaver developers IMHO), but can guarantee well-formedness.

I don't think any solution will be perfect. The best we can hope for is straightforward workarounds.

I'll give some background info and then I'll show how an attribute driven template language for Cocoon could look. The discussion is based on TAL http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL, Tapestry http://jakarta.apache.org/tapestry/ and some of the functionallity in JXTG.

Lucky me, I just made my first site with Plone a couple of months ago.

We need two kinds of constructions: expressions and directives.

Expressions
===========

Expressions are the "${expr}" stuff in e.g. JXTG and should be use able both in text in attributes and element content. Do we need the "$"? Couldn't we just use "{expr}" as in XSLT?

I'm glad someone else said this. I totally agree. If I understand correctly, the reason behind the '$' character was to differentiate JXPath and JEXL expressions. Since the current thought is that we'll standardize the lookup syntax, why the extra character. It can be said that people are used to JXTG, but far more people are used to XSLT-style attribute value substitution.


Also bear in mind that JXTemplateGenerator is already written and code complete. Any new syntactic sugar would presumably be in a different sitemap component (even if it were abusively named org.apache.cocoon.transformation.JXTemplateGeneratorV2). Everyone used to the old syntax just uses the old JXTG implementation in their sitemap declarations (I love Cocoon's design for this by the way).

IIUC TAL doen't use embeded expressions but instead replace element and attribute content with replace directives (in attributes). It might make it even more Dreamweaver friendly as you can look at example content instead of expressions in your design window. But it makes template writing much harder IMO. We could have such replacement directives if people want it but, I would prefer having embeded expresions as well.

I as well. In addition, I think that the optimum template language would be as close to the appearance of the output document as possible. (Yet another reason I don't personally care for explicit forEach, if and chose elements; they make it harder to see at a glance how it will look after processing.)


Directives
==========

TAL uses one name spaced attribute for each directive, e.g.:

<p tal:condition="here/copyright"
   tal:content="here/copyright">(c) 2000</p>

Other than the fact that I would have rathered the attribute were tal:test instead of tal:condition for brevity's sake, this syntax had proven to be extremely powerful and easy to understand in my experience.


Tapestry instead uses only one attribute, "jwcid", with the directive name as content.

<tr jwcid="loop">
  <td><span jwcid="insertFirstName">John</span></td>
  <td><span jwcid="insertLastName">Doe</span></td>
</tr>

I'm a big fan of namespacing the attribute for reasons of versioning as well as clearly marking which directives belong to which processor -- both for the processor and for the template author.
.


A problem with "attribute name as directive" is that xml attributes are unordered. So in the case you need e.g. a double loop over an element, test if you want to perform a loop or do a loop and test each element, a mechanism for deciding the order is needed. TAL uses a predetermined order for the directives. That is far to implicit for my taste and it doesn't solve the double loop. I would prefer to do something more explicit like:

<p tal:define-1="x /a/long/path/from/the/root"
   tal:condition-2="x"
   tal:content-3="x/txt"
   tal:attributes-4="class x/class">Ex Text</p>

Sounds good on paper, sounds like a royal PITA in practice. Determining whether attribute A should be set before the first condition but after the second condition which determines the content... Complexity can rise dramatically and quickly with this. I'd say the template should lose the ability to do a small set of corner cases if, 95% of the time, the simpler syntax has noticeably lower complexity.


I think the desire for this comes from the desire to make HTML-oriented templates from the template directives. Is this correct and is this the correct focus? If the template language is focused on producing semantic XML -- where the XML reflects the structure of the problem at hand and not its presentational form -- simpler syntaxes are much more useful. As is the case with Plone, the focus on HTML output mandates more complex processing options than is otherwise necessary.

If HTML output is a primary design concern and HTML templates are made so much easier/possible, will anyone on a deadline keep SoC firmly in their heads? Once this happens, what advantage does Cocoon have over JSP w/ taglibs? I'm honestly curious. If HTML-oriented templates are the norm, and the pipelines would consist of the successor to JXTG and an HTML serializer, what's the point? I don't mean to invoke a slippery-slope fallacy as I think this is a real possibility.

When the XML and the logical data structure are intimately related, things tend to fall into place with a minimum of decision making. Then transform. Then serialize.

NIH
===

First some motivation about why I don't think that TAL or Tapestry templates are good alternatives for using as is in Cocoon (besides that its much more fun to implement them ourselves ;) ). AFAIU both TAL and Tapestries directives are very closely connected to the both frameworks respective component models. We need something that works with our world view. Furthermore TAL is develped by the Zope community so everything is in Phyton style, and at that feels less natural, at least for me.

Yes, the TAL processor doesn't even enforce well-formedness. It's a pattern matching replacement syntax that would require some reworking of assumptions in order to work with Cocoon. It also takes away the ability to easily drop a ${value} directive in your attributes and content areas, thereby increasing the directive-to-normal markup ratio which I care about so much.


A Proposal
==========

Based on the previous I propse that the attribute driven template language should be invoked like:

<element do="<directive>" attr1="...">
  <content>...</content>
</element>

The idea is that the attribute "do" triger the execution of the directive. "do" is just an example we could make the trigger attribute configurable and/or namespaced so that it doesn't colide with your "host" XML language.

Interesting, but it worries me. It helps with the attribute ordering issue, but starts to feel a little too much like a formal programming language to me. Today, the syntax handles conditionals, data replacement, etc. As time goes on, the desire to add new directives (or God forbid, arbitrary pluggable processing directives) will come. Namespace URI versioning would be very important here. I'm more inclined to simply back up and say, "Conditionals get processed first, then looping, then content replacement," and be done with it. As I said before, I think more flexible "do" constructs just lend themselves to easier handling of complex HTML output-oriented templates. Once again, I'm uneasy with this is direction.


example:

<div do="if(count(cart/item) == 0)">
  Your cart is empty
<div>

<snip what="forEach, for, context, let, macro, eval, content, replace"/>

And would these be chained?

 <table>
   <tr do="if(count(cart/item) == 0); forEach(cart/item)">
     <td>${index}</td>
     <td>${description}</td>
     <td>${price}</td>
   </tr>
 </table>

So much for avoiding the complexity of a general programming language. Simpler may leave fewer options, but that's not always a bad thing. If all options need to be handled, you're looking back at XSP, the ultimate in this area.

Several directives
------------------

So, how do we handle multiple directives for one element? We could handle the TAL example above like:

<p do="let(x=/a/long/path/from/the/root;if(x);content(x/txt);attributes(class=x/class)">

  Ex Text
</p>

Yeah, that's what I thought. I pity the template writer that much content with someone else's templates.


Connection to JXTG
------------------

The directives are almoust defined in such a way that they could be translated to a tag based templating language like:

directive(param_1=value_1,...,param_n=value_n)

<=>

<jx:directive param_1="value_1" ... param_n="value_n"/>

Maybe we could find a attribute directive language that allows for complete correspondance. And make tag or directive syntax selectible and in such way make this effort compatble with JXTG?

We're talking about a radically different syntax. Shouldn't we refer to it with another name even if that name is temporary and trite? From where these discussions are headed, JXTG is frozen in time. If the syntax is changed radically, backward compatibility is out the window.


JX2?
JX-ng?
CTemplates
XTemplates
FlowTemplates
Eugene
Whatever

That or there are substantial redundancies in the code. A Perl-like "there are at least two ways of doing everything." If that's what people here want, so be it. Not worth starting a fight over.

Externaly defined directives?
-----------------------------

If we chose to allow extenally defined directives they probably should be given own namespaces to avoid clashes.

Absolutely agree! Different problem scopes warrant different identifiers.

Formating?
----------

IMO most of the basic formating can be done in a special conversion layer as we have discussed in the convertor thread.

Agreed.

I still think macros should be handled in transformations rather than Java code, but there it is.

- Miles Elam



Reply via email to