Velocity directives
A directive is a Velocity keyword starting by a "#", for example "#set", "#if", "#foreach", etc.
Directives can be thought of as "instructions" for handling rendering in a model. They can be used to define variables (#set), apply logical conditions (#if), iterate over collections (#foreach), etc.
To avoid misinterpretations the name of the directive can be bracketed with "{" and "}"
Most used directives
#set
The #set directive is used for setting a value. A value can be assigned to either a simple variable or an object property. "#set" always defines a "global variable" wherever you use it.
You cannot set a variable to "null" explicitly
NB : if the value to be assigned is null then it will not be assigned!
#foreach / #end
The "#foreach" directive is used to loop through a list of objects. Within the "#foreach" directive 2 local variables are created to represent : - the current item in the loop (you can name it as you want) - the "$foreach" object providing properties like "count", "index", "hasNext", "first", "last", "parent", "topmost". The visibility of these variables is only "local" (visible only in the "#foreach" block). A variable defined with "#set" inside a "#foreach" block remains global (visible outside of the block). The "$foreach" object is an instance of org.apache.velocity.runtime.directive.ForeachScope.
Examples :
Loop with given values :
Loop with an object (array, list, collection) :
Map iteration :
Break the current iteration :
"$foreach.count" loop counter ( 1 to N ) :
"$foreach.index" zero-based index ( 0 to N-1 ) :
"$foreach.hasNext" ( true if not last item ) :
Nested loops :
It's possible to access outer loops properties by using "$foreach.parent" or "$foreach.topmost" (e.g. $foreach.parent.index or $foreach.topmost.hasNext).
#if / #else / #elseif / #end
Conditional output or instructions
Examples :
#if / #end :
#if / #else / #end :
#if / #elseif / #else / #end :
#include
The #include directive allows to import a local file at the current position. The file is included "as is" (as a text file, not rendered through the template engine, not parsed). If more than one file will be included, they should be separated by commas. A variable can be used instead of a literal filename. Any files to which #include refers must be included under "TEMPLATE_ROOT" ( the "bundle" directory for Telosys ).
Examples :
#parse
The #parse directive allows to import a local Velocity template file. The file is parsed by the Velocity engine. Only one argument is accepted (only one file for each call, other arguments are ignored). A variable can be used instead of the literal filename. All the variables defined before the "#parse" call are usable in the parsed file. All the variables defined in the parsed file are usable in the primary file after the "#parse" call. Any templates to which #parse refers must be included under "TEMPLATE_ROOT" ( the "bundle" directory for Telosys ).
Examples :
#parse can be used inside "parsed files". Recursion is permitted (with a condition to stop recursion).
Primary file :
"foo.vm" file with recursive "parse" :
Other directives
#stop
The #stop directive stops any further rendering and execution of the template. This is true even when the directive is nested within another template accessed through #parse or located in a velocity macro.
The resulting output will contain all the content up to the point the #stop directive was encountered. This is handy as an early exit from a template.
Example :
#break
The #break directive stops any further rendering of the current "execution scope". An "execution scope" can be - a directive with content : #foreach, #parse, #evaluate, #define, #macro, or #@somebodymacro - the current template ("root scope"). Unlike #stop, #break will only stop the innermost, immediate scope, not all of them.
Examples :
#evaluate
The #evaluate directive can be used to dynamically evaluate a statement (piece of Velocity code). This allows to evaluate a string that is created dynamically at render time. '#evalute' works like '#parse' but with content that comes from a variable in memory instead of a file (it's possible to evaluate multiple lines).
Examples :
#macro
Velocity "macros" allow you to define a portion of VTL code which will then be reusable several times. They are often called "Velocimacro".
Example : basic macro (without argument)
Arguments : A Velocimacro can take any number of arguments (0 to N arguments). When the Velocimacro is invoked, it must be called with the same number of arguments with which it was defined. Each argument is a local variable and can never be used outside.
Example : macro with 2 arguments
NB : Macros are not functions, they are designed to render and they cannot return a value. But you can simulate a "return value" by setting a variable in the macro and using it after calling the macro or by setting the result as a string.
Example : "Function like call" getting the result as text (with quotes)
#define
The #define directive allows to assign a block of code to a variable. The associated block of code can contain any valid code.
The code associated with a variable by #define is executed when the variable is referenced.
The type of the variable created by #define is org.apache.velocity.runtime.directive.Block$Reference
Example :
Differences between "#define" and "#macro" : " - #macro" accepts parameters so that they provide a context for creation of local variables - "#define" structure (unless it contains macros) only works with global variables
Last updated