The point is missed

Museum of public mistakes and unfinished projects

Tell don’t ask templating?

leave a comment »

Velocity is my favourite templating language so far due to it’s simplicity, general applicability and it’s clean cut between implementation and layout. It is dynamic so changes take place right away. And it’s fast.

I do have one complaint though and it is a trait velocity shares with a lot of templating languages: All decisions are made with if/else statements. This is fine in a lot of cases but there are times when it gets annoying.

I have been toying lately with a publishing tool that features an internal wiki-syntax for content and velocity for the general layout. Before I move on, let’s first have a velocity crash-course:

A velocity file is called a template, when the template is rendered it is given a context. The context contains the data for the template.

So if I add data to my context from my java-code like this:

context.put("variable", "value");

I can access it from my velocity template like this:

The variable contains the value $variable

Ok, not that hard. The context can contain any object and I can call any method on the object. I can retreive data from the object by accessing properties on the object. My problem starts to surface, anything I want to show in my template I have to make available via a getter or similar. That is not all:

public void draw(Object object) {
  if (object instanceof Circle){
    drawCircle((Circle) object, canvas);
  }
  else if (object instanceof Rectangle) {
    drawRectangle((Rectangle)object, canvas);
  }
}

Ever seen code like this?

This is the textbook example of where polymorphism can make the code cleaner:

public void draw(Shape shape) {
  shape.drawOn(canvas);
}

Much nicer. Any shape now draws itself on the provided canvas. I don’t have to do any instanceof anymore.

How does this relate to my velocity problem? Well, let’s say that I have a wiki-parser that given some input will give me a syntax-tree. Lets keep the syntaxtree simple. Let’s say that I can represent a single paragraph that can contain one or more links:

This is a paragraph with a [[http://google.com][link]] that links to google.

Ok, Now I want this to turn this into html. There could be multiple reasons why I would want to use a template for this but I won’t go into them now. First let’s look at how I would generally do this in java:

public class HtmlBuilder implements WikiBuilder {
  private Writer output;

  public HtmlBuilder(Writer writer) {
    output = writer;
  }
  public void link(String href, String description) {
    output.write("<a href='");
    output.write(href);
    output.write("'>");
    output.write(description);
    output.write("</a>");
   }
  public void text(String text) {
    output.write(text);
  }
}

That builder would be used by the parser:

WikiParser parser = new Parser(input);
Article artilce = parser.parse();

article.direct(new HtmlBuilder(output));

Ok, there are more than one ways to do this but you get the point: the parser reads the reader input and builds a syntaxtree article. The article directs the builder and calls text(text) for regular text and link(href, description) for links. That makes the HtmlBuilder write the equivalent html on the output-writer.

Ok, but the javacode contains a lot of overhead in that writer.write(…); stuff. We want to make a template for html-documents:

context.put("article", parser.parse());

Now to the tamplate:

#foreach($element in $article)
   #if($element.isText)$element
   #elseif($element.isLink)<a href="$element.href">$element.description</a>
   #end
#end

Yuck! how many if/else would I need for a complete wiki syntax? What if the syntax is not flat but a composite-tree? I would like the template to behave like my HtmlBuilder did in the java-example. But I can’t…

This is how I would like to do (in principle)

#class builder
   #def link($href, $description)<a href="$href">$description</a>#end
   #def text($text)$text#end
#end
$article.direct($builder)

Wouldn’t that have been neat? So what templating languages out there have I missed that does that? It would be simple enough to implement with dynamic proxies in a templating language like velocity. Rather than doing what most templating engines do, pull the data from the objects and present in the output, we push data through a template. I have been playing with programs where no method returns anything (all methods are declared as void). This is almost the inverse of FP and the results can be quite interesting. Would templating like this be a good application for that style of programming?

Written by johlrogge

August 30, 2008 at 6:40 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: