[Helma-dev] FreeMarker Template Introduction
Juerg Lehni
juerg at scratchdisk.com
Fri Nov 25 13:38:27 CET 2005
Despite the complete lack of reactions I write one more email that
explains the FreeMarker template extension a bit in more detail.
I now prefer this extension a lot over the Velocity extension, it
fits in very nicely, and since the latest updates it is even
compatible with helma macros, and offers access to all values that
normal skins have access to as well, plus much more (maybe a bit too
much at the moment, but that can easily be narrowed down in the
RhinoWrapepr):
Through the RhinoMapper, FreeMarker allows Scriptable objects
(JavaScript scopes) as the rootMap that exposes all data to the
template. So all i need to do is create a new scope that uses the
global scope as its prototype, add the "this" reference to it, and
pass this to the renderer. All the global objects known in the
JavaScript scopes (res, req, session, path, root, etc.) are then
available in the template engine as well, through the same notation.
And since I added support for normal skin macros (and an extended
version, see bellow), macros in "this", "root", and even global
macros can be called just like in skins.
So here's a little overview (without giving a full introduction in
FreeMarker):
- Conditional statements, expressions:
<#if !session.user?exists>
Hello ${session.user.name}
<#else>
<a href="/login">Login</a>
</#if>
- Loops:
<table>
<#list res.data.nodes as node>
<tr>
<td>${node_index + 1}.</td>
<td>${node.name}<#if node_has_next>,</#if></td>
</tr>
</#list>
</table>
- Macros:
<@this.macro foo="bar" bla="bla" />
<@globalMacro />
various types can be passed as parameters: arrays, hashes, etc:
<@root.macro array=[1, 2, 3, 4] />
<@root.macro hash={ "foo": "bar" } />
- Macros with nested content:
<@this.nested foo="bar">Nested text</@>
function nested_macro(param, nested) {
// param.foo == "bar"
// nested == "Nested text"
}
- Call methods and JavaScript functions:
${ this.href() }
${ this.getParent().href() }
But that's just the tip of the eisberg. You can define macros and
functions in the template language (FTL) as well, include other
templates, localization is built in (but not supported by the
extension as of yet. I still need to find a nice way to do so).
All in all I think this is very powerfull and fits into Helma very
nicely. I would prefer if some parts of the syntax could be name
differently, but I guess that's the price I'll have to pay to have
flexibility. : )
One could also argue about too much freedom...
One thing that I've changed is notation: response, request are not
known in the templates. Use req.data / res.data instead, just like
you would in the scripts. I could add these objects for backward
"compatibility", but as other things have changed as well, I don't
mind that they're not there any more. It's more consistent in that
way. And I couldn't simulate session, because this has the same name
in JavaScript and the Skin templates, so the session that links to
session.data would override the session object that would give access
to for example session.user.
It would be great to hear other opinions on this. FreeMarker feels
like a natural extension to Helma and is very flexible in the way
it's integrated. I'm pretty impressed with it. Maybe it could be
considered for a tighter integration at a later point?
Jürg
More information about the Helma-dev
mailing list