cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <sylv...@apache.org>
Subject Re: [Design] JXTG 2.0 (Just say no!)
Date Thu, 02 Dec 2004 14:23:45 GMT
Miles Elam wrote:

> Ummm...  Hold on second while I don my flame-resistant underwear.


<snip what="history of template languages"/>

> Why tag libraries?  To deal with the excessive code in the markup.  If 
> you really need code in markup for your corner case, tag libraries 
> aren't going to help the situation much.  You need code.
>
> So here we stand discussing how to go back to big balls of tag library 
> mud.  We have a glimpse of better things with Flow.  Why aren't we 
> examining that model for further direction?  Why are we going 
> backwards?  Arbitrary Java code executing in the markup but with a 
> prettier face?  Great.  I'm so happy, I could eat the six month old 
> leftovers rotting in my friend's tupperware.
>
> CAN' T WE COME UP WITH A BETTER IDEA!?!  There are some really smart 
> people on this list.  C'mon!
>
> What have tag libraries been used for?
>
> 1. A macro language
> 2. Data generation
> 3. Data formatting
> 4. Backend processing
> 5. Making programming languages out of markup
> 6. Data replacement
>
> Let's go down the list.
>
>        1. A macro language
>
> XSLT or any of the other markup transformation syntaxes can handle 
> this.  No code or tag API needed.  STX: an easy-to-use syntax enabling 
> a SAX stream with a minimal memory footprint.  Side effect-free.  
> Highly cacheable.  The cached SAX events for JXTemplateGenerator are 
> put in the cache for future use -- same story with a 
> JXTemplateTransformer or any JXTemplate* successor or whatever.  
> Nothing lost by using a simple transformation language.  The best 
> part?  It's simple.
>
>        2. Data generation
>
> Raise your hands.  Let's see who you are that still thinks after all 
> that we've learned from web development history that 
> <esql:execute>SELECT * FROM MYTABLE WHERE COLUMN1 = 0</esql:execute> 
> is a good idea and the best we can come up with?  I admit that I was 
> one of "those" people that was trying to get a standard relational 
> database API in Flow.  So wrong.  SO WRONG.  I would like to thank the 
> developers on this list for their insight and wisdom on this point.
>
> If you are savvy enough to write a Java class that implements the Tag 
> interface, you are certainly smart enough to write a POJO for use with 
> Hibernate (or whichever object persistence mechanism you prefer).  In 
> fact, the way things are going and with the tools being made 
> available, the Tag interface is *harder*.  And an implementation of 
> Tag verses a Javascript object or data structure?  The difference in 
> complexity level isn't even funny.


You miss an important point here: many Cocoon users are not able to 
write Java code, and even less a Tag implementation. The purpose of 
taglibs and template languages is to provide pre-packaged higher-level 
constructs that hide the underlying complexity.

Take a look at ESQL for an extreme example in this area :-)

>      3. Data formatting
>
> Let's call a spade a spade here.  We've got how many variations that 
> need to be handled?
>
> boolean, integer types, floating point types, dates/timestamps, 
> strings, XML fragments, selection from limited choices (if 0, say 
> "none" -- if 1, say "one" -- if more, say "many"), and objects (which 
> are basically .toString() calls unless it has properties that are 
> plain old datatypes -- in which case you use the other handlers).
>
> That's what?  Seven different formatters?  Done.  Finished.  Do we 
> really need a tag library for that?  Make them reusable components 
> that transformers can use as needed.


AFAIK, this is exacly the idea: have a set of Formatters (or Convertors) 
and share them between template engines, and CForms.

>      4. Backend processing
>
> We don't like to admit it, but we've all wondered, "What if this 
> custom tag could trigger a cache invalidation or do some workflow 
> or..."  Bad idea.  Bad idea.  Backend processing in your markup 
> template is a horrible idea.  Do it in an action or better yet in Flow.


I partially agree here. When a pipeline is used to produce the view, 
i.e. what is sent back to the user, then there should be no side effects.

Now there are times where pipelines are used as part of the application 
logic, and is such cases having components with side-effects is allowed. 
Such pipelines can be thought of as business logic functions implemented 
with pipelines rather than with traditional programming languages.

>      5. Making programming languages out of markup
>
> <foo:if>, <foo:for-each>, <foo:eval>, etc.  Why the foreplay?  If 
> you're gonna write a programming language, at least have the decency 
> to not base it on markup.  These aren't really different from saying
>
> <% if (test.isTrue()) { %>
>   <foo/>
> <% } %>
>
> or XSP's
>
> <xsp:logic>
> if (test.isTrue()) {
>   <foo/>
> }
> </xsp:logic>
>
> IMO constructs like this should be context-dependent on the task at 
> hand.  For example, wouldn't it have been easier if instead of
>
> <jx:for-each var="person" items="${people}">
>   <jx:if test="${person.name != 'Mean Mike'} ">
>     <friend>${person.name}</friend>
>   </jx:if>
> </jx:for-each>
>
> you had
>
> <friend jx:context="${people}" jx:test="${name != 'Mean 
> Mike'}">${name}</friend>
>
> Same thing.  Not a programming language though.  Data injection 
> tailored to the task at hand.  This is the problem domain that 
> JXTemplateGenerator is made to solve.


Know what? This is a form of taglib also, although it's driven by 
attributes rather than elements.

We use this technique to inject some XSLT-like instructions in HTML 
pages as attributes, and these annotated HTML pages can then be compiled 
to regular XSLs.

So yes, both forms are strictly equivalent, although the attribute-based 
syntax allows for more compact notation and is more Dreamweaver-friendly.

> What is the for-each doing?  Setting a scope -- a context.  Look back 
> in the templates you've made.  How many <jx:if> elements wrapped more 
> than one element?  I have found in my general usage that well over 90% 
> of the time it's just the one child element.  And those 
> <jx:chose/when/otherwise>...  Be honest, how many times have you used 
> that for data formatting rather than structural changes to the 
> markup?  Listing stuff like "yesterday" or "today" or "last week" 
> instead of the raw date.  That's a boatload of markup to do what 
> amounts to a java.text.ChoiceFormat method call.
>
> If it's that complex, why isn't it reflected in your data model 
> instead of your markup's wannabe programming language?


Because the choice of displaying "yesterday", "today" or "last week" is 
not a concern of the data model: the model only holds a java.util.Date.

>      6. Data replacement
>
> And here we come to the meat.  This is where the I18nTransformer does 
> its magic.  This where JXTemplateGenerator does its thing.  One hit 
> wonders where the markup has been altered to fit the problem at hand, 
> not the general definition of a tag library.  Where does the following 
> I18nTransformer example fit in?
>
> <input type="submit" value="Submit" i18n:attr="value"/>
>
> It can if all it does it translate <foo:i18n-submit/> to the above for 
> "real" processing.  Stylesheet.


Or tags as attributes, as outlined above.

> Data injection.  That's what custom markup is really good for.  It's a 
> domain-specific problem.  Tag libraries are for general case 
> problems.  But the general case is already handled by the existing 
> transformers' API.
>
>
>           -------------------------- o0O0o -------------------------
>
>
> So what are the use cases that require tag libraries?  More 
> specifically, what are the use cases that require tag libraries that 
> will be made cleaner by skipping XSP?
>
> What would I prefer?  Keep XSP as it is.  It's shite, but it's 
> powerful shite.  It's for the edge; those pesky corner-cases that 
> refuse to go away; the last 1%.
>
> * XSP is Cocoon's mod_rewrite. *


Yes. And that's why it won't be deprecated soon, IMO :-)

It's a gun that may allow you to shoot in your foot, but may also save 
your like in extraordinary conditions.

> Don't code around mod_rewrite.  Let it be the method of last resort.  
> Find a model that allows the logic, data structures and code to live 
> elsewhere.


Well, pushing the comparison, why do we have a mod_proxy when 
mod_rewrite can do it also? Simply because mod_proxy does only one 
thing, but does it in a more understandable way. It provides a proxy 
feature for those you want proxying without risking to shoot themselves 
in the feet.

> Leave data injection and formatting to the template 
> generator/transformer.  Look at Flow and find something like it.  
> Maybe not exactly Flow, but a lot closer to it than the world of 
> ASP/PHP/JSP and tag libraries.
>
> I would prefer something like
>
> <Cats xmlns:data="http://org.apache/cocoon/data">
>   <Cat data:context="${cats}" name="${name}" sex="${sex}" age="${age}"/>
> </Cats>
>
> and/or
>
> <Cats xmlns:data="http://org.apache/cocoon/data">
>   <Cat data:context="${cats}">
>     <Sex>${sex}</Sex>
>     <Name data:test="${name}">${name}</Name>
>     <Age data:test="${age != -1}">${age}</Age>
>   </Cat>
> </Cats>
>
> I would prefer this to the current situation of
>
> <Cats xmlns:jx="http::">
>   <jx:for-each var="cat" items="${cats}">
>     <Cat name="${name}" sex="${sex}" age="${age}">
>   </jx:for-each>
> </Cats>
>
> or
>
> <Cats xmlns:jx="http::">
>   <jx:for-each var="cat" items="${cats}">
>     <Cat>
>       <Sex>${sex}</Sex>
>       <jx:if test="${cat.name != null}">
>         <Name>${cat.name}</Name>
>       </jx:if>
>       <jx:if test="${cat.age != -1}">
>         <Name>${cat.age}</Name>
>       </jx:if>
>     </Cat>
>   </jx:for-each>
> </Cats>
>
> Sure, macros can alleviate this.  But macros are band-aids on a 
> usability/design defect.  This talk of macros and tag libraries I 
> think has more to do with our frustrations with the current models 
> than actual demonstrated need.  So instead of a discussion about how 
> the tag library API should be defined, why not make the simplest 
> interface for the outside world first.  And only after that's done, 
> talk about implementation details like tag libraries.


Ok. My conclusion about this is twofold:
- taglibgs should be triggered by attributes and not only by elements,
- we need a Convertor/Formatter service

The second point is already agreed upon, and I personally like the first 
one.

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Mime
View raw message