Working with issue custom fields in velocity


This page tries to introduce the approach to take when trying to work with an issue custom field that you may be unfamiliar with. In short, this page will illustrate type discovery, and how the velocity context (and general web searching for types can help you achieve your goals)


Wherever you are working with Velocity Templates in JEMH, there is a Velocity Context of useful variables are exposed in-app that you can use, the values of such entries are also usually linked to online API documentation (to allow you to discover more about the objects!)

Postfunction order

FYI, when using postfunctions, JEMH postfunctions need to be placed after the reindex, as, changes made during the transition will not yet be applied.

Velocity Context

Where there is a velocity template, there is a velocity context, we document that context near the editor, eg in a postfunction:


In velocity, for example in a Postfunction template, $issue is how you refer to the issue object, but it is a TemplateIssue wrapped type with some useful extra methods for template use:


type / link


type / link



You can see from the linked Javadoc that the TemplateIssue has a method getCustomFieldValue() , what you get back is an Object to cover the variety of data types than can exist

Discovering the custom field returned value type

Discovering what the custom field data type is can be achieved with the following, which also checks whether there is a value or not:

#if ($!issue.getCustomFieldValue("customfield_28900")) the cust field has a value #set ($cfValue = $!issue.getCustomFieldValue("customfield_28900")) the cust field value is type $cfValue.getClass().getName() #else there is no value #end

Common types can include java.lang.String (just text), collections of things are also possible, eg it could be a list collection like java.util.ArrayList, javadoc for core Java classes is widely available ( ).

Working with a list

#if ($!issue.getCustomFieldValue("customfield_28900")) the cust field has a value #set ($cfValue = $issue.getCustomFieldValue("customfield_28900")) the cust field value is type $cfValue.getClass().getName() //we figured out it was a list of things #foreach ($aListValue in $cfValue) The option is type $aListValue.getClass().getName() #end #else there is no value #end

This can allow the content data types to be discovered, e.g. For a Checkbox custom field type, it would refer com.atlassian.jira.issue.customfields.option.LazyLoadedOption, a glance at the API will show there is a useful getValue() that returns a String type:

Example for Checkboxes

We create a Checkbox custom field with three values (Red, Green and Blue). The following script shows what these values are and makes a decision based on the presence of Blue:

#if ($!issue.getCustomFieldValue("customfield_10200")) the cust field has a value #set ($cfOptions = $!issue.getCustomFieldValue("customfield_10200")) the cust field value is type $cfOptions.getClass().getName() #set ($blueWasSelected = false) #foreach ($anOption in $cfOptions) The option is type $anOption.getClass().getName() So, option found with value: $anOption.getValue() #if ($anOption == "Red") Its red #elseif ($anOption =="Blue") #set ($blueWasSelected = true) Its blue #end #end #if ($blueWasSelected==true) Blue was selected so do something, like inhibit... #end #else the cust field has no value #end

Example mail sent for this case