Velocity jumpstart

SiteVision modules often uses the Apache Velocity template engine when rendering output. Velocity is a markup language that has a small footprint, a simple syntax and good performance.

This page briefly shows you the basics of Velocity.

Accessing objects

When you write code in a Velocity template, you have access to all objects available in the Velocity context. Each object is registered with a name and you use the name (prefixed with a dollar-sign) to access the object.

For example: if an instance of a java.util.ArrayList is registered as "myList" in the context, you access it as follows in your Velocity template:

$myList   

Invoking methods

You invoke methods as you would in Java.

For example: if an instance of a java.util.ArrayList is registered as "myList" in the context, you invoke the size() method as follows in your Velocity template:

$myList.size()

Invoking no-args get methods

If you invoke a get-method that has no arguments, you can use the short-name notation Velocity provides.

For example: if you want to call the getThing() method of an object that is registered as "aObject" in the Velocity context you can do so in three ways:

$aObject.getThing()
$aObject.Thing
$aObject.thing

The first one is obvious since it uses the full method signature. The two below is using the short-name notation to execute the getThing() method.

Comments

All lines that starts with two ## are considered as single line comments. For example:

## This is a single line comment   

Comments that span multiple lines are demarcated with #* and *#. For example:

#*
This is a multiple
line comment!
*#   

Selections

Selections in Velocity is done using the familiar if/elseif/else idiom. For example:

#if ($something == 1)
...
#elseif ($somethingIsTrue)
...
#else
...
#end

Note that #elseif is one word (i.e. no space between else and if). Also note that the end of a selection statement is demarcated with an #end

Iterations

Iterations in Velocity is done with the foreach construct. Hence, to iterate in Velocity you must have some kind of collection/iterator.

An example of how to iterate the items in a java.util.ArrayList registered as "myList" in the context:

#foreach ($aItem in $myList)
   $aItem.doSomething()
   ...
#end

Note that you specify the name of the item (i.e. $aItem above) variable as you like (a variable name can only contain characters ['a'..'z', 'A'..'Z', '0'..'9', '-', '_']). Also note that the end of the foreach construct is demarcated with an #end

Predefined variables in foreach loops

Velocity provides special predefined variables that is available during execution of the foreach construct

#foreach ($item in $someIterableThing)
   $velocityCount  ## 1-based counter (legacy variable)
   $foreach.count  ## 1-based counter
   $foreach.index  ## 0-based counter
   $foreach.first  ## boolean - whether or not this is the first entry
   $foreach.last   ## boolean - whether or not this is the last entry
#end

You can break out of a foreach loop with the #break directive

#foreach ($item in $someIterableThing)
   ...
   ## Break out of the loop when 3 items has been processed
   #if ($foreach.count == 3)
      #break
   #end 
#end

Assigning objects and values

Variables is assigned using the set construct. For example:

#set ($myThing = 1)  

You can use actual values in assignments and concatinate them when the variable is set

#set ($name = 'Stina')
#set ($age = 30)
#set ($sentence = $name + ' is ' + $age + ' years old')

You can also do simple mathematical operations when the variable is set (or re-set). For example:

#set ($count = 0)
#foreach ($aItem in $myList)
  #set ($count = $count + 1)
  ...
#end

$count should be equal to $myList.size()

Caveats

No null assignments
You can not assign a null value to a Velocity object. If you try to assign or use a null value, the previous value will be used instead!

For example, the result of:

#set ($myVariable = "Hello")
My variable: $myVariable <br>
#set ($myVariable = $aObject.thisMethodReturnsNull())
My variable: $myVariable   

will be:

My variable: Hello <br>
My variable: Hello

No parsing of assignments enclosed in single quotes

If you assign something enclosed in single quotes, it will not be parsed.

For example, the result of:

#set ($myVariable = '$aObject.Thing')
Hello $myVariable

will be:

Hello $aObject.Thing

Tips & Trix

Check for null values

You can do a simple if-statement to check if a value exist. For example:

#if ($aObject)
	$aObject.xxx
#end

Ensure no null value

You can use the ! operator to ensure nothing will be printed if it is null.

$!aObject.doSomething()

An example: If you have a link object (named "link" on the context) and it has no title (i.e. getTitle() method returns null). If your Velocity template look like this:

<a href="..." title="$link.Title">A link</a><br>
<a href="..." title="$!link.Title">A link again</a>

Then the rendered result will be this:

<a href="..." title="$link.Title">A link</a><br>
<a href="..." title="">A link again</a>

E.g. When Velocity doesn't find what you specify, your statement will be printed 'as-is'!

Explicit statement

Sometimes you have to explicitly tell Velocity where your statement really ends. This is done with curly brackets.

For example if you want to call the getThing() method on aObject and some text is directly after your statement:

${aObject.Thing}text

(Without brackets Velocity would look for a method or variable named "Thingtext" and fail)

Null check/assignment workaround

As stated above - Velocity ignores null assignments. A common strategy to work around this is to use the "Check for null value" strategy stated above. You sometimes end up with code like this:

## Ensure doStuff() returns non-null value
#if ($myObject.doStuff())
   #set ($thing = $myObject.doStuff())
   $thing.doThis()
   $thing.doThat()
   ...
#end

The downside with this strategy is that it requires two subsequent method invocations. That is of course a really bad thing if the method does costly things.

Tip! The ScriptUtil interface of the SiteVision Public API allows you to do it more efficiently using the getNonNullValue() method. The code above can be better utilized as:

## Assign thing - Boolean.FALSE if result is null
#set ($thing = $scriptUtil.getNonNull($myObject.doStuff()))

#if ($thing)
   $thing.doThis()
   $thing.doThat()
   ...
#end

Velocity and (X)HTML

Ensure that string demarcation characters in method arguments does not collide with characters in HTML. A simple solution for this problem is to use single quotes instead of quotes. For example:

<a href="$aObject.doThingWithString('A String')" title="">A link</a>