Methods
Methods are references that consist of a leading "$" character followed a VTL
Identifier, followed by a VTL Method Body
. A VTL Method Body
consists of a VTL Identifier followed by a left parenthesis character ( "(" ),
followed by an optional parameter list, followed by right parenthesis character (
")" ). These are examples of valid method references in VTL:
$customer.getAddress()
$purchase.getTotal()
$page.setTitle( "My Home Page" )
$person.setAttributes( ["Strange", "Weird", "Excited"] )
The first two examples -- $customer.getAddress()
and
$purchase.getTotal()
-- may look similar to those used in the
Properties section above, $customer.Address
and
$purchase.Total
. If you guessed that these examples must be
related some in some fashion, you're correct!
VTL Properties can be used as a shorthand notation for VTL Methods. The Property
$customer.Address
has the exact same effect as using the Method
$customer.getAddress()
. It is generally preferable to use a
Property when available. The main difference between Properties and Methods is that
you can specify a parameter list to a Method.
The shorthand notation can be used for the following Methods:
$sun.getPlanets()
$annelid.getDirt()
$album.getPhoto()
We might expect these methods to return the names of planets belonging to the sun, feed our earthworm, or get a photograph from an album. Only the long notation works for the following Methods.
$sun.getPlanet( ["Earth", "Mars", "Neptune"] )
## Can't pass a parameter list with $sun.Planets
$sisyphus.pushRock()
## Velocity assumes I mean $sisyphus.getRock()
$book.setTitle( "Homage to Catalonia" )
## Can't pass a parameter
As of Velocity 1.6, all array references are now "magically" treated as if they are fixed-length lists. This means that you can call java.util.List methods on array references. So, if you have a reference to an array (let's say this one is a String[] with three values), you can specify:
$myarray.isEmpty()
$myarray.size()
$myarray.get(2)
$myarray.set(1, 'test')
Also new in Velocity 1.6 is support for vararg methods. A method like:
public void setPlanets(String... planets)
or even just:
public void setPlanets(String[] planets)
(if you are using a pre-Java 5 JDK), can now accept any number of arguments when called in a template:
$sun.setPlanets('Earth', 'Mars', 'Neptune')
$sun.setPlanets('Mercury'
$sun.setPlanets()
## Will just pass in an empty, zero-length array
Property Lookup Rules
As was mentioned earlier, properties often refer to methods of the parent object. Velocity is quite clever when figuring out which method corresponds to a requested
property. It tries out different alternatives based on several established naming
conventions. The exact lookup sequence depends on whether the property name starts
with an upper-case letter. For lower-case names, such as
$customer.address
, the sequence is
-
getaddress()
-
getAddress()
-
get("address")
-
isAddress()
For upper-case property names like $customer.Address
, it is slightly
different:
-
getAddress()
-
getaddress()
-
get("Address")
-
isAddress()
Rendering
The final value resulting from each and every reference (whether variable, property,
or method) is converted to a String object when it is rendered into the final
output. If there is an object that represents $foo
(such as an
Integer object), then Velocity will call its .toString() method to resolve the
object into a String.
Formal Reference Notation
Shorthand notation for references is used in the examples above, but there also is a formal notation for references:
${mudSlinger}
${customer.Address}
${purchase.getTotal()}
In almost all cases, you'll use the shorthand notation for references, but in some cases the formal notation is required for correct processing.
Suppose you're constructing a sentence on the fly where $vice
is
used as the base word in the noun of a sentence. The goal is to allow someone to
choose the base word and produce one of the two following results: "Jack is a
pyromaniac." or "Jack is a kleptomaniac." Using the shorthand notation would be
inadequate for this task. Consider the following example:
Jack is a $vicemaniac.
There is ambiguity here, and Velocity assumes that $vicemaniac
, not
$vice
, is the Identifier that you mean to use. Finding no value
for $vicemaniac
, it will return $vicemaniac
. Using
formal notation can resolve this problem.
Jack is a ${vice}maniac.
Now Velocity knows that $vice
, not $vicemaniac
, is
the reference. Formal notation is often useful when references are directly adjacent
to text in a template.
Quiet Reference Notation
When Velocity encounters an undefined reference, its typical behavior is to output the image of the reference. For example, suppose the following reference appears as part of a VTL template.
<input type="text" name="email" value="$email"/>
When the form initially loads, the variable reference $email
has no value,
but you prefer a blank text field to one with a value of "$email". Using the quiet
reference notation circumvents Velocity's typical behavior; instead of using
$email
in the VTL you would use $!email
. So
the above example would look like the following:
<input type="text" name="email" value="$!email"/>
Now when the form is initially loaded and $email
still has no value,
an empty string will be output instead of "$email".
Formal and quiet reference notation can be used together, as demonstrated below.
<input type="text" name="email" value="$!{email}"/>