File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Servlets and the fly likes Template engine Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "Template engine" Watch "Template engine" New topic

Template engine

Charles OBrien

Joined: May 23, 2002
Posts: 10
Currently I am working on developing a servlet that needs to keep the presentation layer separate from the business layer, so that the designers can easily alter the general look and feel without too much complexity.
For the templates I am using XML being transformed by XSL.
I am not sure how to get variables to be parsed in the templates, nor what would be the best way to store the templates.
Templates basically would have the form of:
It does not really matter. The templates could be kept inside a file and loaded through a stream or kept inside a database and the database is queried to load the template into the template cache.
The part where I am at a loss is once the template is loaded the variables need to be parsed with the corresponding variables in the servlet. I have no idea how to parse the variables in the template, now a string or so once loaded.
Once the variables are parsed, the resulting XML in a string or so is sent to the XSL transformation system to be sent as output.
Any help would be greatly appreciated on the parsing or other recommendations you may have.
As an aside I am attempting to stay away from the systems such as WebMacro so we can have sometime simple and built to what we need. Once I have a basic core it will be relatively easy to expound upon.
Charles O'Brien
Mike Curwen
Ranch Hand

Joined: Feb 20, 2001
Posts: 3695

you use the term "now a string or so" a few times. Does that mean that the templates, once loaded into the template cache, might *not* be a simple java.lang.String ?

If so, then why not load your XML template as a DOM object ? Then it's a 'simple' matter of "walking the tree".
If you have something like this in your template:
<h2>Hello <tag>$name</tag></h2>

When walking the tree, you'd be looking for all of the <tag> nodes and replacing the node with the contents of your variable on the server-side, that matched the contents of that node. (your servlet would assume the contents of the tag would be a variable name. In this way you might even dispense with the $ sign, since you'd be stripping it off.

To resolve it in the servlet the easiest way, I'd put all my variables into a HashMap, keyed to a string that you would then present to your designers as "ok, this is the list of things you can get".

Having said that though, this really strikes me as re-inventing a wheel that's been done many, many times.

Have you looked at Velocity? It's just about the simplest templating I've seen and I quite like it.
Charles OBrien

Joined: May 23, 2002
Posts: 10
Thank you Mike for your answer...
Basically by "string or so" I was just noting that any type is fine for the data to be kept in, however, most likely a string would be the most feasible.
I will look into what you have said.
Also, I have looked into Velocity, I just don't need something as packed with all the loops, conditionals, etc... just simple ol' variable parsing.
Once again, greatly appreciated.
[ May 11, 2003: Message edited by: Charles OBrien ]
Charles OBrien

Joined: May 23, 2002
Posts: 10
Let me also just clarify for others who may see this topic.
Say there is a template "row_body" which looks like:
A template "wrapper":
<navigation>Navigation Stuff</navigation>
<copyright>Here is The Copyright</copyright>
So, the templates are loaded into the template cache in preparation to be used.
1) Data is queried from the messages table, the information for the row_body, author and message
2) The author data is assigned "author" variable, and the queried message data is assigned "message" variable.
3) The template "row_body" is parsed in a while loop for each of the messages with author and message varying based on what was returned from the database.
4) The $body is parsed in the wrapper template with the concated string with the results of the while loops templates, still in XML format.
5) The resulting XML blob like:
<navigation>Navigation Stuff</navigation>
<context>I am message 1</author>
<context>I replied to you</author>
<copyright>Here is The Copyright</copyright>
is than transformed with XSL to HTML
6) The HTML is outputted
Basically, a simplistic template system.
Mike Curwen
Ranch Hand

Joined: Feb 20, 2001
Posts: 3695

First you say:
I have looked into Velocity, I just don't need something as packed with all the loops, conditionals, etc... just simple ol' variable parsing.

But then you say:
3) The template "row_body" is parsed in a while loop for each of the messages

It looks like you *do* need looping. I agree that Velocity may be "more" than some systems would need. But on the other hand, what's simpler than this?:

Your parsing piece would create the appropriate authors ArrayList of author Maps. The template merging engine takes care of the rest.

One problem I see with using just a tag like <rowbody> is that it took me a couple reads of your numbered steps to understand that the <rowbody> is self-looping. That is, the parsing engine you're trying to code would understand that when it hits <rowbody> it should go find some data (which data?), and loop over the results, swapping and replacing anything found inside the <rowbody> node that begins with a $.

Worse, it should also be understood by your parser that $body means "go find that <rowbody> template and do it's logic". Does $body *always* mean that? Does it *always* mean use <rowbody> ?

This was a point I missed out on until the 2nd time I was editing this message Either I'm thick tonight, or there is inherint confusion when mixing the invokation of parsing/merging functions between XML tags and "things beginning with $"

I don't like the idea of "baking in" the looping stuff into an XML tag. It starts to make XML look like a programming language, which it's not. (flame war ON!)

I suppose you could clarify this by naming the tag something like <repeatingRowBody>, and instead of $body, use <repeatingRow />. But then the issue for the first becomes "repeating on what", and remains for the second "using what template"? Where in the template is this specified? If you say "well that will be hardcoded by whatever uses the template"... what about the case where you have two $body or <repeatingRow /> tags in a single template? Which one is which? You either can't use this template for anything else, other than your exact hard-coded instance that says "the first time you see it, it means this, the next time, it means this other thing...) or you now need an attribute on the tag to let your parser know which tag is which.

Which brings me around to thinking that the looping should not be part of the tag. Looping should be invoked by a simple command (like #while or #foreach) and I don't feel this over-complicates matters for template designers (mostly HTML monkeys?)

And yes, I'm gonna make one last sale point... Velocity isn't tied to HTML output either, as I've demonstrated by using your XML tags. You can still continue on to do an XSL transform, although using plain <tr><td></td></tr> tags is of course, supported as well.

I've seen Velocity used in a commercial product to produce email messages from templates. And umm.. I kinda copied it just recently at my own job. The idea... not the code!

and p.s Velocity also has handy features like #parse and #include, for nested templates.
[ May 12, 2003: Message edited by: Mike Curwen ]
I agree. Here's the link:
subject: Template engine
It's not a secret anymore!