Article Using Velocity

Widget content is implemented using a version of the Velocity templating language.

When should I use the Velocity templating language?

Velocity is one of the two languages used to implement server side scripts used by scripted customizations. Velocity is a templating language best suited to conditional rendering of content to form a string (for example, the HTML rendering of a widget) whereas Server-side Javascript is better suited for data processing. Velocity has full access to the Widget/Scripting API to interact with the Verint Community platform.

Velocity Language Syntax

Variables, properties, and methods

Variables and extensions

$[!][{ ][a-z,A-Z][a-z,A-Z,0-9,-,_]*[ }]

Variable and extension names must start with a dollar sign and an alphabetic letter.

When the value of the variable is null, $variable will render the name of the variable and $!variable will render nothing.

${variable} is the formal notation for variables and distinguishes variable references within text, for example see${variable}this.

Properties

$[!][{ ][a-z,A-Z][a-z,A-Z,0-9,-,_]*.[a-z,A-Z][a-z,A-Z,0-9,-,_]*[ }]

Dot-syntax is used to reference properties on variables and extensions.

When the value of the property is null, $extension.Property will render the name of the extension and property and $!extesion.Property will render nothing.

${extension.Property} is the formal notation for properties and distinguishes property references within text, for example see${extension.Property}this.

Methods

$[!][{ ][a-z,A-Z][a-z,A-Z,0-9,-,_]*.[a-z,A-Z][a-z,A-Z,0-9,-,_]*([optional_parameter_list])[ }]

Dot-syntax is used to reference methods on variables and extensions.

When the return value of the method is null, $extension.Method() will render the name of the extension and method and $!extesion.Method() will render nothing. If the return value is void, nothing will be rendered.

${extension.Method()} is the formal notation for methods and distinguishes method references within text, for example see${extension.Method()}this.

Directives

#set

#set($reference = [argument])

Assigns a value to a variable or property where:

  • $reference is a variable or property reference.
  • [argument]is:
    • a method, variable, or property reference
    • a literal boolean (true or false)
    • a literal number ([0-9]*.[0-9]*)
    • a literal string in single or double quotes
    • an array definition ([$item1, $item2, $item3,... $itemN])
    • a mathematic expression:
    • Addition: #set($n = $n + 1)
    • Subtraction: #set($n = $n - 1)
    • Multiplication: #set($n = $n * $x)
    • Division: #set($n = $n / $x)
    • Modulus: #set($n = $n % $x)

When [argument] is a literal string, strings in double quotes will be parsed whereas strings in single quotes will not be parsed.

#store

#store($reference)
  [script resulting in the value assigned to the variable]
#end

Assigns the result of executing a block of script to a variable where

  • $reference is a variable reference.
#store($result)
  <a href="$user.ProfileUrl">$user.DisplayName</a>
#end

#if

#if([condition])
  [script to execute when if condition is true]
[
#elseif([condition])
  [script to execute when elseif condition is true]
]*
[
#else
  [script to execute if no conditions are true]
]
#end

Conditionally renders templates where:

  • [condition]is:
    • a Boolean expression:
      • Equal: #if($x == $y)
      • Greater: #if($x > $y)
      • Less: #if($x < 100)
      • Greater or Equal: #if($x >= 100)
      • Less or Equal: #if($x <= 100)
    • a non-Boolean variable, property, method, or literal reference (true if not null, otherwise false).

     

  • [script...] is any Velocity or literal text.

#foreach

#foreach($item in $items)
[#each]
  [script to execute for each item]
[
#before
  [script to execute before each item]
]
[
#after
  [script to execute after each item]
]
[
#between
  [script to execute between each item]
]
[
#odd
  [script to execute for every other item, including the first]
]
[
#even
  [script to execute for every other item, starting with the second]
]
[
#nodata
  [script to execute if $items is null or empty]
]
[
#beforeall
  [script to execute before all items, if there are items]
]
[
#afterall
  [script to execute after all items, if there are items]
]
#end

Renders templates for each item within a collection of items where:

  • $item is the variable containing each item in the $items collection when executing #each, #odd, and #even scripts.
  • $items is a variable, property, or method resulting in a collection of items.
  • [script...] is any Velocity or literal text.

#each is the default template, so,

#foreach($item in $items)
  $item.Name
#end

is equivalent to

#foreach ($item in $items)
#each
  $item.Name
#end

#format

#format($formatString)
[#token()]
  [script resulting in the numeric token's value]
[#token($parameterName)]
  [script resulting in the named token's value]
#end

Inserts token values into a tokenized format string where:

  • $formatString is the expression resulting in a string containing zero-based numeric ({0}) or named ({name}) tokens. The format string cannot mix numeric and named tokens.

Token values are defined using one or more #token directives within the #format block. Each #token can optionally identify a token name.

#format('{0}, {1}, and {2}')
  #token()
    One
  #token()
    Two
  #token()
    Three
#end
#format('{a}, {b}, and {c}')
  #token('a')
    One
  #token('b')
    Two
  #token('c')
    Three
#end

#registerEndOfPageHtml

#registerEndOfPageHtml([key])
  [script to render at the bottom of the completed HTML page]
#end

Registers a block of HTML at the end of the completed HTML page where:

  • [key] is an optional variable, property, or literal string value identifying the unique key with which the contained markup should be registered.
  • [script...] is any Velocity or literal text.

If the [key] is not supplied, the contained script will always be added to the bottom of the completed HTML page. If the [key] is supplied, the first #registerEndOfPageHtml directive executed will have its contained script added to the bottom of the completed page.

#evaluate

#evaluate($script)

Execute a string as a Velocity script where:

  • $script is a variable, property, or literal string containing Velocity script.

#stop

#stop

Stops execution of the widget immediately.

#stop should only be used for debugging purposes. To hide a widget, use $core_widget.Hide() instead.

##

## [comment]

Identifies a comment where:

  • [comment] is a single line of unexecuted text.

#*

#* [comment lines] *#

Identifies a multi-line comment where:

  • [comment] is one or more lines of unexecuted text.

Widget Extension Usage with Velocity

Most of the Platform API is available to velocity script, implemented as a set of widget extensions automatically available in the context of an executed Velocity script. Additionally, custom extensions can also be accessed.

For more information, please refer to the full set of Widget Extensions.

When a widget extension method accepts a dictionary of options, those options can be passed using the Velocity syntax

"%{ Key1 = $value1, Key2 = $value2 }"

Note that the entire dictionary is passed as a formatted string.

Example Widget Extension Usage

The following example will retrieve and render a list of blog posts in the current blog

## Retrieve the current blog. If there is none, hide the widget
#set ($currentBlog = false)
#set ($currentBlog = $core_v2_blog.Current) #if (!$curentBlog) $core_v2_widget.Hide() #end ## Retrieve the 5 latest blog posts #set ($blogPosts = $core_v2_blogPost.List("%{ BlogId = $currentBlog.Id, PageSize = 5 }")) #foreach ($blogPost in $blogPosts) #beforeall <ul> #each <li><a href="$core_v2_encoding.HtmlAttributeEncode($blogPost.Url)">$blogPost.Title</a></li> #afterall </ul> #nodata <span class="message">No blog posts</span> #end

Tips and Tricks

Getting the current Foreach Index

If you want to track the current index you will need to store the index as a local variable.  Here is an example of how you can do this.

#set($index = 0)
#foreach($tag in $core_v2_tags.Current)
  #each
	 #set($index = $index + 1)
#end

Concatenating strings

Oftentimes you will need to combine two or more strings and pass the result as a parameter to a method, to do this, place the variables within double quotes:

#set($newVal = "$val1$val2")

Adding a variable to the end of a URL before a period

You may need to pass a Velocity variable as part of a URL, and you may need to pass it at the end of the URL before a period.  For example, if you are creating a URL for api.ashx/v2/groups/$groupId/members/users/$userId.json where $userId is a local Velocity variable, $userId will not be formatted correctly because it is looking for a property named json on $userId.  To get around this, you can use the strict formatting option for Velocity variables, like the following

api.ashx/v2/groups/$groupId/members/users/${userId}.json

Working with null values

When Velocity evaluates

#set ($variable = $someExtension.someMethod())

if $someExtension.someMethod() evaluates to null, $variable will not be changed. It will still have its previous value. To reuse the $variable variable (in a #foreach, for example), instead use:

#set ($variable = false)
#set ($variable = $someExtension.someMethod())

This is how links widgets must be implemented. 

Programmatically modifying/building dictionary options

It is already possible to do calls like this

$core_v2_foo.Bar(42, "%{ key1 = "value", key2 = "value2" }

Sometimes it is necessary to programmatically build the options dictionary for looping or logical reasons. This can be done as follows:

#set ($options = "%{}")
$options.Add(newKey, "newValue")

Try $core_help.Dump()ing $options to see the full set of methods available for operating on the dictionary.