Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents


JEMH exposes JIRA's notification templates and macros, allowing extensive customization of the content that your JIRA outputs.  This can mean anything from a small modification of an existing default template, to a complete overhaul of your entire template collection.

Templates are constructed using the Velocity Template Language.  If you plan on making use of custom templates, it is recommended that you have an understanding of Velocity by reading the Velocity User Guide.  It is also worth checking out Atlassian's documentation regarding Customising Email Content.

Customization pointers

Consulting the Velocity Context list

You can see what methods are available for use in your templates by referring to the Velocity Context List (JEMH>Template Sets>Velocity Context).  The list shows the key that represents a class.  The class is then referred to in the template by using a leading "$" followed by the key:

Code Block

By consulting the class associated with that key, you can find the method that is needed.  Then, this method can be used by adding a method body to the end of the key in the template:

Code Block

Useful variables to remember

Velocity reference

Represented class


TemplateIssue representation of JIRA issue in context


Comment associated with JIRA issue event


NotificationRecipient - the recipient of the current notification that is being rendered.  Each recipient has their own notification rendered.  This may or may not be associated with a JIRA user.


The base url of your instance, including context path if set


IJEMHVelocityContextUtils.html JEMH Helper class


JIRA's default templates make extensive use of Macros.  These are located with JIRA_INSTALL/atlassian-jira/WEB-INF/classes/templates/email/macros.vm, but since JEMH 1.6.x these can be viewed via JEMH>Template Sets>Macros.  To customize content, it may be necessary to take existing macros and re-work them to suit your needs.  To assist with this, the User Macros tab allows you to define your own macros and test their functionality.  See How Do I Use Macros for more information.

Using Jira Macros in Template

As mentioned Jira’s default templates make extensive use of Macros, and since JEMH 1.6.x these can be viewed via JEMH>Template Sets>Macros. These Macros can be used as they are in your own Templates, for example:

Macro in JEMH

Using Macro in Template

Using Jira Macros as Template guidelines

In some cases, you might need to use something similar to an existing Jira Macro but cannot use the exact Macro. In this case, you can use JEMH to view existing Jira Macros as a guideline. For example, I might want to use the 'Fix Version' Macro from the last example, without putting the values in a table:

In this example we can take the heading, and value outside of the Table Row and use them independently.

Code Block
#if ($issue.fixVersions && $issue.fixVersions.size() >0)
    #foreach ($fixfor in $issue.fixVersions)
        $ #if ($velocityCount != $issue.fixVersions.size()), #end 

Value in template:

Custom Templates can result in IGNORED event status

When JEMHC processes a webhook Event, the default templates indicate when a comment or field is rendered. If you start with an EMPTY template and leave out the following, your event will likely end up with an IGNORED status as JEMHC believes that no ‘content’ was rendered.

Include the following as appropriate:

Code Block

Specific Examples

Here there are some specific examples of velocity mark-up for extracting particular issue fields.  Sometime specific minimum versions of JEMH are required

Rendering user Avatars

since JEMH 3.1.15

Code Block
#if ($!issue.getAssignee())
#rowWrapperNormalBegin('' 'wrapper-special-margin')
 #set ($assignee = $issue.getAssignee())
 #set ($avatarUrl = $jemhUtils.getUserAvatarURL($assignee, 24))
 <table style="border-radius: 10px;background:#FFEEFF;padding:10px;width: 600px;height: 50px;">
     <tr><th width="100">Your agent is:</th><td><img src="$avatarUrl" width="24" height="24" alt="alt text"></img> $assignee.getDisplayName()</td></tr>

looks like:

Issue Watchers

since JEMH 1.6.22

Code Block
#set ($allWatchers = $watcherManager.getCurrentWatcherUsernames($issue))
#foreach ($aWatcherUsername in $allWatchers)
#set ($applicationUser = $userManager.getUserByName($aWatcherUsername))
- watcher userName: $aWatcherUsername , email = $applicationUser.getEmailAddress(),displayName = $applicationUser.getDisplayName()

Custom Fields

Here is an example of including a custom field that has the numeric ID 1481.  First, you need to locate the ID of a custom field. There are two ways to do this:

1) JIRA Admin>Issues>Fields>Custom Fields

Click the configure icon for your target custom field, and hover over the edit link.  Your browser should show the custom field ID in the link URL.

Code Block!default.jspa?id=10500

2) Database Query

The custom field ID can also be found by querying your JIRA instance's database:

Code Block
SELECT * FROM customfield WHERE cfname LIKE '%mycustomfield%';

Once you have the custom fields ID, you can use the $issue to get the custom field value:

Code Block
#if ($!issue.getCustomField("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 
  Some Custom Field : $issue.getCustomFieldValue("customfield_11300")

The method $!issue.getCustomField has been removed since Jira 8.19.0. Please use the following if using a later version. For more info see:

Code Block
#if ($!customFieldManager.getCustomFieldObject("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 
  Some Custom Field : $issue.getCustomFieldValue("customfield_11300")

User Properties

This example script will list all user properties and show all text/string and boolean values.

Code Block
#set ($targetUser = $issue.getReporter())
#set ($userProps = $userPropertyManager.getPropertySetForUserKey($targetUser.getKey()))
userPropertySet class: $userProps.getClass()
#set ($prpKeys = $userProps.getKeys())
Keys class: $prpKeys.getClass()
propertysSet size size: $prpKeys.size()
----------- user properties ---------------
#foreach ($aKey in $prpKeys)
#set ($propType = $userProps.getType($aKey))
$aKey[$propType] : #if ($propType==1) boolValue=$userProps.getBoolean($aKey) #elseif ($propType==5) stringValue=$userProps.getString($aKey) #elseif ($propType==6) textVal=$userProps.getText($aKey)#end]

Example extract:
"atl.jira.admin.current.project" = $userProps.getString("atl.jira.admin.current.project")

Rendering a Custom Field as Wiki mark-up

The velocity context contains $wikiRenderer for this purpose (see the API, its linked in the Velocity Context docs within the JEMH TemplateSet section):

HTML output

Code Block
#if ($!issue.getCustomField("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 

TEXT output

Code Block
#if ($!issue.getCustomField("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 

The method $!issue.getCustomField has been removed since Jira 8.19.0. Please use the following if using a later version. For more info see:

HTML output

Code Block
#if ($!customFieldManager.getCustomFieldObject("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 

TEXT output

Code Block
#if ($!customFieldManager.getCustomFieldObject("customfield_11300") && $!issue.getCustomFieldValue("customfield_11300")) 

Access custom field values from a Parent Issue

The following velocity can be used to access the custom field values of a parent issue in a notification for a sub-task issue.

Code Block
#set ($cfVal = $customFieldManager.getCustomFieldObject("customfield_11300") )
Custom field=$issue.getParentObject().getCustomFieldValue($cfVal)

Embedding a specific Attachment (Jira 8.0.0 + )

Ensure that Include Attachments in Notifications is enabled in your JEMH > Notification > Non-Jira/Jira Notification Project Mappings.

The Script below will render an attachment link to the notification where “test.txt” is a placeholder additionally this will embed the file to the notification.

Code Block
 $rendererManager.getRenderedContent("atlassian-wiki-renderer", "[^test.txt]", $issue.getIssueRenderContext())

how the link looks:

Rendering Customer request types
titlesince 3.3.40

The script bellow can be used to retrieve information related to Customer Request Types. This only works in JSM projects that use Customer Request types.

Code Block
#set($customField = $customFieldManager.getCustomFieldObjectByName("Customer Request Type"))

#set($requestType = $jemhUtils.getRequestType($customField.getValue($issue).toString()))

No request type

How it looks

Additional Examples

For Additional examples see the following pages

Page Tree

Related articles

Filter by label (Content by label)
cqllabel in ( "macro" , "template" , "notification" , "velocity" , "events" ) and space = "JEMH" and type = "page"
labelsevent listener jemh issue notification