Customize Email Templates

Scenario

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:

$issue

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:

$issue.getKey()

Useful variables to remember

Velocity reference

Represented class

Velocity reference

Represented class

$issue

TemplateIssue representation of JIRA issue in context

$comment

Comment associated with JIRA issue event

$recipientEmail

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.

$baseurl

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

jemhUtils

IJEMHVelocityContextUtils.html JEMH Helper class

Macros

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.

#if ($issue.fixVersions && $issue.fixVersions.size() >0) #text("template.fix.versions"): #foreach ($fixfor in $issue.fixVersions) $fixfor.name #if ($velocityCount != $issue.fixVersions.size()), #end #end #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:

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

looks like:

 

 

Issue Watchers

since JEMH 1.6.22

Components

The Components field can contain multiple values, due to this it means that you would need to iterate over each value to be able to gather the relevant value, for example component name.

Labels

The Labels field can contain multiple values, due to this it means that you would need to iterate over each value to be able to gather the relevant value, for example the name of each label.

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.







2) Database Query

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





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

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:

User Properties

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

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

TEXT output

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

TEXT output

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.

Embedding a specific Attachment (Jira 8.0.0 + )

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

Script
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.

how the link looks:

 

Rendering Customer request types since 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.

How it looks

 

Additional Examples

For Additional examples see the following pages

 

Related articles