There are a few simple ideas (goals) behind Cambridge Template Engine.
- Less cluttered, easily readable, developer and browser friendly template files
- Speed
- Safety
- True separation of concerns
To achieve these goals Cambridge was designed differently than it’s alternatives like JSP, Freemarker or Velocity. The main idea in template syntax in Cambridge is not to add any code blocks or wrapping elements into your existing template markup. The markup languages like html and xml already have a well structured hierarchy of tags. Every tag has a built in scope. (We know where it starts and ends.) Cambridge makes use of this scope which already is in your template files. You associate behaviors to your tags and that behavior becomes active within the scope of that tag.
To achieve the performance goal, every template file gets parsed only once and then gets normalized into an efficient form to be rendered. What do I mean by an efficient form? Every web developer knows that DOM is. When your template files are parsed, a DOM like tree for all your template elements is created by Cambridge. Traversing this tree while rendering would work, but would be ineffective in many performance critical scenarios. What Cambridge does is basically to flatten this tree into a list of fragments to be printed to an output stream. A fragment might be static or dynamic based on if it is an expression to be evaluated or a tag which has some dynamic behavior associated or any standard tag or text. This new normalized form is used by Cambridge again and again until the template file is changed and need to be re-parsed.
So lets have a look at how some of the features of Cambridge compare with other alternatives.
Expressions
Evaluating expressions are very similar in almost all templating solutions for Java. JSP, Freemarker, Cambridge, Play Framework all uses the ${…} syntax to escape from html and print the value of an expression. Velocity is a bit different, it doesn’t require you to use braces, you can just type $userName to get the value of the userName variable.
Every template engine has a different underlying expression language. JSP uses the Jsp Simple Expression Language. Freemarker and Velocity have their own expression languages. Play Framework uses Groovy which actually is much more than an expression language.
Cambridge comes with a built in expression language that I’ve developed which depends on Antlr runtime. However, thanks to the extensible nature of Cambridge, you are not limited to that. If you want more features with a little sacrifice of performance, you can use MVEL or OGNL as your expression language in your Cambridge templates.
For many people, built-in expression language should be enough, however I must say that I’m also very impressed by MVEL.
Conditional Blocks
JSP with JSTL
No true else/elseif support.
<c:if test="${loggedInUser != null}">
<div class="hello">Hello ${loggedInUser}</div>
</c:if>
<c:if test="${loggedInUser == null}">
<div class="logIn">Please log in</div>
</c:if>
JSP with inline Java code
<%
if (loggedInUser != null) {
%>
<div class="hello">Hello <%=loggedInUser%></div>
<%
} else {
%>
<div class="logIn">Please log in</div>
<%
}
%>
Velocity
#if ($loggedInUser)
<div class="hello">Hello $loggedInUser</div>
#else
<div class="logIn">Please log in</div>
#end
Freemarker
#if ($loggedInUser) <div class="hello">Hello $loggedInUser</div> #else <div class="logIn">Please log in</div> #end
Freemarker
<#if loggedInUser??>
<div class="hello">Hello ${loggedInUser}</div>
<#else>
<div class="logIn">Please log in</div>
</#if>
Play Framework
#{if loggedInUser}
<div class="hello">Hello ${loggedInUser}</div>
#{/if}
#{else}
<div class="logIn">Please log in</div>
#{/else}
Cambridge
In Cambridge, you don’t need to wrap your tags with code blocks or other tags. You just add dynamic attributes like a:if, a:elseif or a:else to your existing classes.
<div a:if="loggedInUser != null" class="hello">Hello ${loggedInUser}</div>
<div a:else class="logIn">Please log in</div>
What if you don’t have an existing tag that wraps whatever content you want to depend on a condition? Then you can use the invisible tag <a:span>.
The output of the following example will only be the text message without the <a:span> tag being rendered in the output.
<a:span if="messages.size != 0">
You have ${messages.size} messages
<a:span>
Loops
JSP / JSTL
<c:forEach var="friend" items="${user.friends}">
<div>${friend.name}</div>
<c:/forEach>
Freemarker
<#list user.friends as friend>
<div>${friend.name}</div>
</#list>
Velocity
#foreach($friend in $user.friends) <div>$friend.name</div> #end
Play Framework
#{list items:user.friends, as:'friend'}
<div>${friend.name}</div>
#{/list}
Cambridge
<div a:foreach="user.friends" a:as="friend">${friend.name}</div>
In the second part of this article, I will write about the performance comparisons of these frameworks.

