Velocity

Table of contents



Syntax

This section is a subset of what you can do with Velocity
For a full guide, see the official Apache Velocity user guide.

Elements Connect uses the Velocity provided by Jira.


Single line comments
## this is a comment
this is not a comment
Multi-lines comments
#*
 A comment
 on multiple lines
*#
Set a variable
#set($variableName = 'value')
Access a variable

Shorthand notation:

$myVariable

Formal reference notation (useful when you want to concatenate a velocity variable to a preset text)

#set($myVariable = "123.45")
${myVariable}Euros
## will be evaluated as "123.45Euros"

Quiet reference notation: evaluate non resolved variable to an empty string (blank)

$!myVariable
Loops
## list first 5 customers only
#foreach( $customer in $customerList )
    #if( $foreach.count > 5 )
        #break
    #end
    $customer.Name
#end
Conditional
#if( $foo < 10 )
    **Go North**
#elseif( $foo == 10 )
    **Go East**
#elseif( $bar == 6 )
    **Go South**
#else
    **Go West**
#end
Relational and logical operators
#set ($foo = "deoxyribonucleic acid")
#set ($bar = "ribonucleic acid")

#if ($foo == $bar)
  In this case it's clear they aren't equivalent. So...
#else
  They are not equivalent and this will be the output.
#end
## logical AND

#if( $foo && $bar )
  ** This AND that**
#end
## logical OR

#if( $foo || $bar )
    **This OR That**
#end
##logical NOT

#if( !$foo )
  **NOT that**
#end
Escaping Valid VTL References
## The following line defines $email in this template:
#set( $email = "foo" )
$email
\$email

renders as

foo
$email
Maths

Velocity has a handful of built-in mathematical functions that can be used in templates with the set directive.

#set( $foo = $bar + 3 )
#set( $foo = $bar - 4 )
#set( $foo = $bar * 6 )
#set( $foo = $bar / 2 )
#set( $foo = $bar % 5 )
Range operator

The range operator can be used in conjunction with #set and #foreach statements.

Useful for its ability to produce an object array containing integers, the range operator has the following construction:

[n..m]

example:

#foreach( $foo in [1..5] )
$foo
#end





Variables

Global variables

Those variables can be used in queries, in Root element and in Columns JSON path.

TypeNameDescriptionAvailable in 
List<String>
$currentCustomfieldValue

Value currently stored in the Elements Connect field.
Returns a list of string if the field contains many values.

(info) This variable works only for Live fields and not for Snapshot fields (see CO-3752)

All queries

Empty when the field does not have any value.

User
$currentUser
Current user connected on the screen.All queries
String
$currentUserLocale

Locale of the current user (ie: fr_FR, no_NO, ...)

All queries
Issue
$issue
Current issueAll queries, expect the "Dashboard Gadget" view of the display query.
Query
$query
Direct access to the query to executeAll queries
String
$userInput

Characters typed by the user in the autocomplete text box.

Edit query when the editor is set to "Autocomplete".
Util
$util

Set of useful functions

All queries
Context
$context 

Current context of the Search query

Search query

Note about types and list of types

In our descriptions, we sometimes say that functions and variables return certain type or list of types. There is no difference in the way we handle this. This is explain in details in the Simple and multiple types section below.


Date

Attributes

TypeNameDescription
String
isoDate

Iso date format 'yyyy-MM-dd'.

ex: 2015-02-22

String
isoDateTime

Iso date time format 'yyyy-MM-dd HH:mm:ss.SSS'.

ex: 2015-08-22 17:31:15.123

String
isoDateTimeZone

Iso date time zone format 'yyyy-MM-dd HH:mm:ss.SSSXXX'.

ex: 2015-08-22 17:31:15.123+02:00

Functions

Any function applicable on String is applicable on Date. In that case, the date is first converted into a String using the historical format 'EEE MMM dd HH:mm:ss zzz yyyy'.

In short, date.serialize(" ") is equivalent to date.format("EEE MMM dd HH:mm:ss zzz yyyy").serialize(" ")

Return typeNameDescription
String
format("...")

This function allows you to format your date freely, if you need a specific formatting.


The ISO-8601 date format ('yyyy-MM-dd HH:mm:ss.SSSXX' ie '2015-08-22 17:55:01.123+02:00' is understood by most of databases.

Issue

Attributes

TypeNameDescription
List<Named value>
affectedVersions
Affected versions
User
assignee
Issue assignee
List<Named value>
components
Components
Date
created
Date when the issue has been created
User
creator
Issue creator

Date or

String


customfield_xxxx

A custom field value - xxxx is the field id

>> Return a List if the field contains multiple values

The return type depends on the type of the custom field. If this is a date custom field (Date or Datetime picker), the return type is a Date. If this is a third party add-on custom field, you can have a look here

In any other case, the value is returned as a String.

String
description
Description
Date
duedate
Issue due date
String
environment
Environment
String
estimate
Estimate
List<Named value>
fixVersions
Fix versions
String
id

ID

Only available on existing issues, on the "Create issue" screen this variable is empty (the issue does not exists)

Named value
issuetype or issueType
Issue type
String
key

Key

Only available on existing issues, on the "Create issue" screen this variable is empty (the issue does not exists)

String
originalEstimate
Original estimate
Issue
parent
Parent of the issue
Available on sub-tasks only, not available on the "Create sub-tasks" screen.
Named value
priority
Priority
Project
project
Project key of the the current issue
User
reporter
Issue reporter (note: not available on the Create issue screen)
Named value
resolution
Resolution
Date
resolutiondate
Content of the "Resolution date" field
Date
resolutionDate
Content of the "Resolution date" field (since 5.9.3)
Named value
security
Security level
Named value
status
Status
String
summary
Summary
String
timeSpent
Time spent
Date
updated
Date when the issue has been updated for the last time
String
vote

This field is deprecated (mispelled). It is still supported for now but we recommend to use votes below instead.

StringvotesVotes count (since 5.9.3)
String
watchers
This field is deprecated (mispelled). It is still supported for now but we recommend to use watches below instead.
StringwatchesWatchers count (since 5.9.3)

Functions

Any function applicable on String is applicable on Issue.

Return typeNameDescription

Date or

String


get("<custom field name>")

or

get("customfield_xxx")

Not recommended

We do not recommend to use this function.
Custom field names are not unique within a Jira instance, therefore Elements Connect picks the first field with the corresponding name.

You shall use the customfield_xxxx notation described above.


>> The return type depends on the type of the custom field

A custom field value - xxxx is the field id

>> Return a List if the field contains multiple values

The return type depends on the type of the custom field. If this is a date custom field (Date or Datetime picker), the return type is a Date. If this is a third party add-on custom field, you can have a look here

In any other case, the value is returned as a String.

(warning) Not for System fields: This is only available for custom fields (native or brought by third party). For system fields, please use notation described abobe (ie. $issue.summary).

Named value 

Attributes

By default a named value is evaluated to its name.

TypeNameDescription
String
id

Id of the value

String
name

Name of the value

Functions

Any function applicable on String is applicable on Name value.

Project 

Attributes

By default, a Project is evaluated to its key.

TypeNameDescription
String
id
The project id
String
key
The project key
String
name
The project name

Functions

Any function applicable on String is applicable on Project.

The string value used in the evaluation will be the project key.

Query 

Direct access to the query to execute - only available in the URL Path / Query attributes of a field configuration.

NameDescriptionExample
abort()

If this instruction is encountered during the evaluation of the query, the query won't be executed.

It is useful if we know in advance that the query won't return any result if certain conditions are not met.

In this example, the query is aborted if the summary of the issue is empty.

#if($issue.summary.length() == 0)
$query.abort()
#end
summary ~ $issue.summary

String 

Functions

Return typeNameDescriptionExample
Integer
length()
Returns the String length
$issue.customfield_xxxxx.length()
> 42
String
intList()
Shortcut for $var.serialize(",")
$issue.affectedVersions.id.intList() 
> 10000,10001,10002
String
prefix(<string>)

Append a string before the string

$issue.issuetype.prefix("hello ")
> hello Bug
String
replace(<current str>,<new str>)

Replace first string matching another string.

$issue.issuetype.replace("story","tale")
> User tale
String
serialize(<string>)
Join the string using a delimiter
$issue.affectedVersions.name.serialize(";") 
> 1.0;1.1;1.2
String
stringList()

Append ' before and after each string and serialize them with a , separator

$issue.affectedVersions.id.stringList()
> '1.0','1.1','1.2'
String
suffix(<string>)
Append a string after the string
$issue.issuetype.suffix(" world")
> Bug world
String
urlEncode()
Convert all characters to be readable in an URL
$issue.summary.urlEncode() 
> Elements Connect+in+a+nutshell

String

encodeURIComponent()

Convert a text to be readable in an URL parameter.

$issue.description.encodeURIComponent()
> hello%20world%20%3F

String

encodeURI()

Convert a text to be readable in an URL.

$issue.description.encodeURI()
> https%3A%2F%2Fvaliantys.atlassian.net%2Fsecure%2FDashboard.jspa

User 

Attributes

TypeNameDescription
String
displayName
Display name of the user
String
emailAddress
Email address of the user
String
name
Name of the user
String
userName
Username of the user

Functions

Any function applicable on String is applicable on User.

The string value used in the evaluation will be the user name.

Return typeNameDescription
boolean
isInGroup(<jira group>)
Is the user member of the given group ?
boolean
isInProjectRole(<role name>,<project key>)
Does the user have the role in the project ?

Util 

Functions

Return typeNameDescriptionExample

Raw text

encodeURIComponent(<string>)

Convert a text to be readable in an URL parameter.

$util.encodeURIComponent("hello world ?")
> hello%20world%20%3F
Raw text
encodeURI(<string>)
Convert a text to be readable in an URL.
$util.encodeURI("https://valiantys.atlassian.net/secure/Dashboard.jspa")
> https%3A%2F%2Fvaliantys.atlassian.net%2Fsecure%2FDashboard.jspa

Context 

Attribute

TypeNameDescriptionExample
Stringname Current execution context
#if($context.name == $context.SEARCH_BASIC_GENERATE_OPTIONS)
	//
#elseif($context.name == $context.SEARCH_BASIC_GENERATE_JQL_QUERY)
	//
#end

Constants

This constants are available in the query of the Search view.

They can be used to determine the execution context of the query and thus to know which velocity variable can be used in the current context

TypeNameDescription
String

SEARCH_BASIC_GENERATE_OPTIONS

Generate options list in the basic search mode

Velocity variables available:

  • $issue 
  • $userInput
  • $currentCustomfieldValue
  • $currentUser
  • $currentUserLocale 
  • $util
String

SEARCH_BASIC_GENERATE_JQL_QUERY

Generate the JQL query from the option selected in the basic search mode

Velocity variables available:

  • $issue 
  • $currentCustomfieldValue
  • $currentUser
  • $currentUserLocale 
  • $util
String

SEARCH_ADVANCED_GENERATE_OPTIONS

Generate options list in the advanced search mode

Velocity variables available:

  • $issue 
  • $userInput
  • $currentUser
  • $currentUserLocale 
  • $util
StringSEARCH_ADVANCED_TILDE_SEARCH

Evaluation of  ~ and !~ clauses in the advanced search mod

Velocity variables available:

  • $issue 
  • $currentUser
  • $currentUserLocale 
  • $util


Custom fields 

Option fields

Elements Connect supports options fields like radio buttonscheckboxes or select list 

TypeNameDescriptionExample

String

getOptionName() Returns the name of the selected option (first option in case of multi select)

$issue.customfield_10005.getOptionName()

> Red

List<String>

getOptionNames() Returns the names of the selected options

$issue.customfield_10005.getOptionName().stringList()

> 'Red', 'Blue', 'Green'

String

getOptionId() Returns the ID of the selected option (first option in case of multi select)

$issue.customfield_10005.getOptionId()

> 10001

List<String>

getOptionIds() Returns the IDs of the selected options

$issue.customfield_10005.getOptionIds().intList()

> 10001, 10002, 10003

Jira software

TypeNameDescriptionExample
List<String>

customfield_xxxxx.getNames() 


(where XXX is the ID of the Sprint field)

Display the Issue sprints names

Current Issue is in one sprint: "Welcome to the Jungle"

$issue.customfield_10005.getNames()

> Welcome to the Jungle

Current Issue is in two sprints: "Welcome to the Jungle" and "Hells Bells"

$issue.customfield_10005.getNames().stringList()

> 'Welcome to the Jungle', 'Hells Bells'


10005 is the ID of the Sprint field

List<String>

customfield_xxxxx.getIds()


(where XXX is the ID of the Sprint field)

Display the Issue sprints ids

Current Issue is in one sprint, with ID 10002

$issue.customfield_10005.getIds()

> 10002

Current Issue is in two sprints, with ID 10002 and 10003

$issue.customfield_10005.getIds().intList()

> 10002, 10003


10005 is the ID of the Sprint field

Jira Service Desk

TypeNameDescriptionExample
List<String>

customfield_xxxxx.getNames() 


(where XXX is the ID of the Organization field)

Display the request organization names

Current request is shared with one organization: "My fantastic organization"

$issue.customfield_10002.getNames()

My fantastic organization

Current request is shared with two organizations: "My fantastic organization" and "Customers first"

$issue.customfield_10002.getNames().stringList()

> 'My fantastic organization', 'Customers first'


10002 is the ID of the Organization custom field

List<String>

customfield_xxxxx.getIds()


(where XXX is the ID of the Organization field)

Display the request organization ids

Current request is shared with one organization, with ID 6

$issue.customfield_10002.getIds()

> 6

Current request is shared with two organizations, with ID 6 and 7

$issue.customfield_10002.getIds().intList()

> 6, 7


10002 is the ID of the Organization custom field

Tempo Accounts

Tempo Timesheets add-on for JIRA embeds a specific customfield type named Accounts. Elements Connect allows to retrieve data from this customfield this way

TypeNameDescriptionExample
String
customfield_xxxxx
Display the display value of selected Account
$issue.customfield_10001
> Account 1 (ACCOUNT1)
String
customfield_xxxxx.id
Display the id of selected Account
$issue.customfield_10001.id
> 2
String
customfield_xxxxx.name
Display the name of selected Account
$issue.customfield_10001.name
> Account 1

Simple types and multiple types 

In the descriptions above, variables and functions are said to return a specific type or a list of values of this type. This is handled exactly the same way by our API.

In short, any single value is considered being a list with a unique value. This allows to apply any function or attribute to any value without the need to check its size.

The only exception is when we convert the expression to a String value for final query evaluation. If there are many elements in a list, we only display the first one (See the examples below).

Example:

ContextExpressionResultExplanation
Issue with one fix version "1.2"$issue.fixVersions 1.2N/A
Issue with two fix versions "1.2" and "1.3" $issue.fixVersions 1.2

When we need to evaluate a query like "SELECT * FROM XXX where version='$issue.fixVersion'", we only take the first element if there are many.

To use the other elements, you need alternate expressions (see below)

Issue with two fix versions "1.2" and "1.3" $issue.fixVersions.stringList() '1.2', '1.3'This way you can write "SELECT * from XXX where version in ($issue.fixVersions.stringList())
Issue of type 'Bug'$issue.issuetype Bug
Issue of type 'Bug'$issue.issuetype.serialize("; ") Bug

As this is considered as a list of one issue type, you can apply the function serialise to it. This only has one element.

As you may also have noticed, the serialize function need a string input, and the default string evaluation for issue type (Named Value) is 'name'.

The expression is equivalent to $issue.issuetype.name.serialize("; ")