You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Jonas Ekstedt <ek...@ibg.uu.se> on 2004/11/16 19:19:20 UTC

A template transformer

Hello

I have created a template transformer similar to JXTemplate and wondered
if you would be interested in it. It can be found at:
http://home.student.uu.se/j/joek8725/template.zip

I'll put it in BugZilla as soon as it gets online again. 

Installation:
* unzip and copy the blocks (conversion and template) to src/blocks
* Apply cocoon.patch
* ./build.sh
* start servlet
* surf to http://localhost:8888/samples/blocks/template/


The TemplateTransformer was based very much on how the TagTransformer
works. Developers can extend the functionality by writing Tag classes.
The transformer is configured in sitemap.xmap where the user can
register tags to different namespaces:

<map:transformer name="template"
      src="org.apache.cocoon.template.TemplateTransformer">
  <tag uri="http://core" name="if"
    src="org.apache.cocoon.template.tag.core.IfTag"/>
</map:transformer>

If there are many tags, the configuration can be put in an external file
and included like this:

<map:transformer name="template"
      src="org.apache.cocoon.template.TemplateTransformer">
<include>resource://org/apache/cocoon/template/tag/core/tags.xml</include>
<include>resource://org/apache/cocoon/someothertags.xml</include>
</map:transformer>

To wet your appetite I have listed a few constructs below:

---
Looping:

<core:for var="i" begin="1" end="10" step="2">
  ${i}
</core:for>

---
Looping over collection:

<core:forEach var="date" items="${collectionOfDates}">
  ${date#short}
</core:forEach>

Note that the date is converted to short form using convertors from the
conversion block.

---

Looping over tokenized string:

<core:forEach var="letter" items="A B C D">
  ${letter}
</core:forEach>

---

I've never particularly liked choose/when so I implemented 
if/elseIf/else instead.

<core:if test="${1 == 2}">
  Not shown
</core:if>
<core:elseIf test="${1 == 3}">
  Not shown
</core:elseIf>
<core:else>
  This is shown
</core:else>

---
Macros:

<table xmlns:m="macros">
  <core:macro namespace="macros" name="row">
    <tr>
      <td>${a}</td>
      <td>${b}</td>
    </tr>
  </core:macro>

  <m:row a="1" b="2"/>
  <m:row a="3" b="${var}"/>
</table>

---
Import:

<core:import uri="somefile.xml"/>

NB. Tags in the imported file are evaluated as well.

---

It is really easy to extend the transformer with your own tags. The Tag
interface looks like:

public interface Tag {

    public void setup(TemplateTransformer transformer,
                      ConvertingEvaluator evaluator, 
                      MapStack variables, 
                      Attributes attributes);
    public void start();
    public void end();
}

Normally you would extend AbstractTag and only implement start() and
possibly end(). 

Cheers Jonas


Re: A template transformer

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Jonas Ekstedt wrote:

>Hello
>
>I have created a template transformer similar to JXTemplate and wondered
>if you would be interested in it.
>
We had discussions at the list about template languages half a month ago 
did you read that?

The conclusion was IIRC, that we like JXTG but not it's implementation 
(to large and scary) and that we need the ability to add custom tags. 
The implementation would be easier to follow and more reusable if the 
object model was factored out (using Carsten's TemplateObjectHelper), 
factoring out the expression language and possibly make it plugable and 
writing the tags as custom tags.

We don't want to complicate life for the users (and ourselves) by differ 
from JXTG whithout very good reasons, and in that case we should 
deprecate the things that we don't like. So the "new" template generator 
should include the JXTG tags.

Looks like that is close to what your taglib does, so it could certainly 
be interesting for us.

>The TemplateTransformer was based very much on how the TagTransformer
>works.
>
Some questions to make it easier to evaluate how your implementation is 
related to other approaches:

Can you compare it with the TagTransformer and explain why you didin't 
build on that?

Have you looked at Jelly. Now Jelly's implementation doesn't seem to fit 
very well into Cocoon, but the way you write tag libs in it seemed neat 
to me. Did you compared your approach to that?

What about caching? In JXTG and Jelly IIUC, the template is "compiled" 
to an internal data structure that use as long as the template isn't 
changed. The main point is that expression compilation and xml parsing 
can be avoided in the sequel. I don't know how much time that is saved 
by doing this instead of interpreting the template every time. Anyway, 
are you doing something like that or would it be worthwhile and easy to add?

<snip/>

Anyway, thank you for your contribution!

/Daniel


Re: A template transformer

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Jonas Ekstedt wrote:
> 
> The TemplateTransformer was based very much on how the TagTransformer
> works. Developers can extend the functionality by writing Tag classes.

It would be good if you either use TagTransformer, or point out what 
improvements are required (from your POV) to the TagTransformer to implement 
templating on top.

Adding YetAnotherTagClassImplementation to the Cocoon is not a good idea, IMHO.

Vadim