cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Miles Elam <mi...@pcextremist.com>
Subject Re: [Design] JXTG 2.0 (Just say no!)
Date Wed, 01 Dec 2004 22:24:18 GMT
Ummm...  Hold on second while I don my flame-resistant underwear.

Okay folks, why are we making tag libraries/interfaces *at all*?  I 
mean it.  I feel like a lemming being driven off a cliff.

Before continuing, I want to take a look at the history of web 
technologies and major milestones.  In the beginning, you had files and 
web servers.  Then people starting writing extensions to the web 
servers and the dynamic web was born.

But the problems with patching your web server for even the slightest 
dynamism were immediately obvious even in the early days of "a patchy 
server".  So CGI (Common Gateway Interface) was born and Perl rose up 
as the dominant web language.  Process creation overhead became an 
issue as the web took off so techniques fro mitigating this were put in 
like mod_perl, servlets, etc., but overall the process stayed the same.

While an improvement over what came before and most definitely useful, 
embedding markup was an absolute pain.  All sorts of hacks rose up to 
programmatically write markup.  But then a lot of people noticed at the 
same time that a lot of their dynamic pages were mostly static markup 
with only a token amount of logic.  Thus the age of ASP, PHP, JSP, et 
al. was born, and it was cool runnings for a while.  If you needed a 
lot of logic, you wrote code with a markup generation library.  If you 
only needed a little logic, you wrote a markup file with code markers 
for logic.

Things started going south when people with no programming experience 
started learning from those ASP, PHP, and JSP examples.  They gleefully 
added huge tracts of code in these files, giving new life to a much 
maligned design pattern known as "big ball of mud".  Soon everyone 
starting getting stuck in the ever-increasing balls of mud.  Simplify!  
Encapsulate!  Componentize!

We'll just add new markup.  We'll call them "tag libraries" and put all 
the code snippets into these markup fragments.  Brilliant!  Now the 
people who don't know how to program can just write markup and coders 
can write stuff further up the chain.

XSP was born at about this point, tag libraries and embedded Java in 
all their splendor, enforcing well-formedness and driving popular usage 
of Cocoon.

People still wrote logic in their markup though.  And even the tag 
libraries became more and more monstrous.  A tag library for databases. 
  A tag library for data formatting.  A tag library to make more tags.  
A tag library to perform backend workflow.  A tag library to do the 
laundry and wash the dishes.  Just to add insult to injury, some 
academic gadflies coined the acronym MVC (Model-View-Controller) and 
starting going on about something called SoC (Separation of Concerns).  
Everything started going gonzo at that point.  HTML was no longer 
supposed to have styling info; that is now CSS's job.  Our data 
repositories may change -- and may or may not be relational databases 
anymore.  Hard-coding database connection strings, table names and 
column names were frowned upon.  Then this brilliant individual named 
Ovidiu thought about how nice it would be to have continuations in web 
development.

Flowscript has entered the building!  (*enter angelic chorus*)  Here we 
had logic in a separate file that generated data structures for display 
and formatting by the templating language.

           -------------------------- o0O0o -------------------------

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.

      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.

      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.

      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.

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?

      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.

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. *

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.  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.

Do you logic in a real programming language.  When you finish, pass the 
result to the template for styling/formatting.

Or am I alone in these feelings?  Pretty interfaces being stuck in the 
middle of big balls of mud!

- Miles Elam


Mime
View raw message