Create custom Theme and Template Sets

In this article we're going to show how to change issue notifications by customizing the JIRA theme and its Template Sets. The customization will change the email header showing a generic support avatar rather than the user avatar when the issue has been created or changed by a user of the developer group. You can follow the same steps to change other aspects of a Theme. 

Step-by-step guide

Create a copy of JIRA theme and it's issue template sets.

  1. Go to Notifications -> Theme -> Create
     

  2. Select the theme, e.g. JIRA (System) as your source of templates and select the Issue Template Sets required (CTRL + left mouse click).
     

  3. Submit. This will copy the JIRA theme, 3 Template Sets and it will take you to the new theme edit screen.  In the macro tab, replace the jemhIncludeStandardActionHeader and  jemhIncludeBody macros with the macros below.
     

Support Jira Header Macro
Depracted (Old)
#macro ( jemhIncludeStandardActionHeader) <tr> <td id="header-pattern-container"> <table id="header-pattern"> <tr> #if ($context.user) <td valign="top" id="header-avatar-image-container"> #if ($jemhUtils.isCreatedByEmailUser()) <IMG height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" SRC='$jemhUtils.inlineImage($jemhUtils.getImageUrl("EmailUserIcon1"))' alt='$messageUtils.getMessage("velocity.macro.action.header.emailUser")'/> #elseif($jemhUtils.hasUserRole($jemhUtils.getOperationUser(),'developers')) <IMG height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" SRC='$jemhUtils.inlineImage($jemhUtils.getImageUrl("SupportUserIcon4"))' alt='$messageUtils.getMessage("velocity.macro.action.header.support")'/> #else <IMG class="image_fix" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" SRC='$jemhUtils.inlineImage($context.user.avatarUrls["32x32"].asText())' alt='$context.user.displayName.asText()'/> #end </td> <td id="header-text-container" valign="middle"> #if ($jemhUtils.isCreatedByEmailUser()) <span>$messageUtils.getMessage('velocity.macro.action.header.emailUser')</span> #elseif($jemhUtils.hasUserRole($jemhUtils.getOperationUser(),'developers')) <span>$messageUtils.getMessage('velocity.macro.action.header.support')</span> #else <a class="user-hover" rel="$context.user.name.asText()" id="email_$context.user.name.asText()" href="$baseurl/secure/ViewProfile.jspa?name=$context.user.name.asText()">$jemhUtils.htmlEscape($context.user.displayName.asText())</a> #end <strong>$messageUtils.getMessage("velocity.macro.action.header.$jemhUtils.webhookEvent")</strong> $messageUtils.getMessage('velocity.macro.action.header.anIssue') </td> #else <td valign="top" id="header-avatar-image-container"> <IMG height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" src="$jemhUtils.inlineImage($jemhUtils.getImageUrl('AnonymousUserIcon'))" alt='$messageUtils.getMessage("velocity.macro.action.header.anonymous")'/> </td> <td id="header-text-container" valign="middle"> $messageUtils.getMessage('velocity.macro.action.header.anonymous') <strong>$messageUtils.getMessage("velocity.macro.action.header.$jemhUtils.webhookEvent")</strong> $messageUtils.getMessage('velocity.macro.action.header.anIssue') </td> #end </tr> </table> </td> </tr> #end
Jira theme
#macro ( jemhIncludeStandardActionHeader) <tr> <td id="header-pattern-container"> <table id="header-pattern"> #if ($jemhUtils.webhookEvent) <tr> #set($authors = $jemhUtils.getChangelogAuthors()) #set($maxRenderedUsersCount = 1) #foreach($user in $authors) #if($foreach.count == $maxRenderedUsersCount) #if ($user) #if ("$jemhUtils.getUserAvatar($user,'32x32')" != "" ) <td valign="top" id="header-avatar-image-container"> <IMG class="image_fix" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" SRC="$jemhUtils.getUserAvatar($user,'32x32')" alt='$jemhUtils.getUserDescription($user)'/> </td> #end <td id="header-text-container" valign="middle"> <a class="user-hover" rel="$jemhUtils.getUserAccountId($user)" id="email_$jemhUtils.getUserAccountId($user)" href="$jemhUtils.getUserProfileUrl($user)">$jemhUtils.htmlEscape($jemhUtils.getUserDescription($user))</a> </td> #else <td valign="top" id="header-avatar-image-container"> <IMG height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" src="$jemhUtils.getImageUrl('AnonymousUserIcon')" alt='$messageUtils.getMessage("velocity.macro.action.header.anonymous")'/> </td> <td id="header-text-container" valign="middle"> <p> $messageUtils.getMessage('velocity.macro.action.header.anonymous') </p> </td> #end #break #end #end <td class="header-text-container"> #if($authors.size() > $maxRenderedUsersCount ) #set($numberOftruncatedUsers = $authors.size() - $maxRenderedUsersCount) &nbsp;$messageUtils.getMessage('velocity.macro.action.header.truncate.users', $numberOftruncatedUsers) #end <strong>&nbsp;$messageUtils.getMessage( "velocity.macro.action.header.$jemhUtils.webhookEvent")</strong> $messageUtils.getMessage( 'velocity.macro.action.header.anIssue') #if($jemhUtils.isCreatedByEmailUser() && false) <strong>$messageUtils.getMessage('velocity.macro.action.header.byEmail')</strong> #end </td> </tr> #end </table> </td> </tr> #end
jemhIncludeBody Macro
Deprecated (old)
#macro ( jemhIncludeBody) <tr> <td class="email-content-main mobile-expand issue-description-container"> <table class="text-paragraph-pattern"> <tr> <td class="text-paragraph-pattern-container mobile-resize-text"> #if ($jemhUtils.isCreateOrInChangeLog($context, 'description')) $jemhUtils.setFieldRendered() $jemhUtils.wikiToHtml($fields.description.textValue()) #end #foreach( $comment in $jemhUtils.filterRestrictedComments($context.comments) ) $jemhUtils.setCommentRendered() #if ($jemhUtils.isJiraUser($comment.author.name.textValue())) <pre>#if($jemhUtils.hasUserRole($jemhUtils.getOperationUser(),'developers'))$messageUtils.getMessage('velocity.macro.action.header.support')#else$comment.author.displayName.textValue()#end $messageUtils.getMessage('commented'):</pre> #end $jemhUtils.wikiToHtml($comment.body.textValue()) #if (!$jemhUtils.isNull($comment.visibility))($messageUtils.getMessage('restrictedTo') <span class="restricted-to-value">$comment.visibility.value.textValue()</span>) #end #if (!$jemhUtils.isNull($comment.updated) && $comment.created != $comment.updated)<span class="edited-label">$messageUtils.getMessage("velocity.macro.action.header.edited")</span> $messageUtils.getMessage("velocity.macro.action.header.by") $comment.updateAuthor.name.textValue()#end #if( $foreach.hasNext )<hr>#end #end </td> </tr> </table> </td> </tr> #end
Jira theme
Generic theme

$jemhUtils.setFieldRendered() and $jemhUtils.setCommentRendered() mark the template as not empty. If you are adding a custom field to your template, remember to write $jemhUtils.setFieldRendered() otherwise you may see a 'email has not been sent as no useful information was set' warning.

Previewing the Theme

JEMHCloud provides a preview tool that allows you to see the review your template against read event data. 

  1. Go to Notifications -> Preview. Select the new Issue Created Template set named Issue Created: Issue Created Jira Support (User)

  2. Test the template sets with different preview contexts. Examples:

    Developer user creates an issue using UI
     


    User creates an issue via email


    Developer user comments an issue via UI

  3. Repeat steps using other template sets and preview contexts. 

Update Issue Notification Mappings

Once you've tested your new theme, you can activate it assigning its template sets to your notification mappings. 

  1. Go to Notifications -> Notification Mappings -> Email -> Pen

     

  2. Theme Changer, select JIRA Support (User). This action updates all events with the new theme's template sets.

     

  3. After submit, email notifications will use the new theme.

 

It's recommended to test your theme with Test Cases. Also, keep an eye on Auditing -> Events.

The latest sent emails are recorded in Auditing -> Outbound Messages. Click in one of the audit items, Cog -> View HTML Body

Pop-up shows the real email sent to a user.

JEMH Server Template Compatibility

Please note that JEMH Server templates are not compatible with JEMH Cloud.  Attempting to use a template copied from JEMH Server may result in errors or other unexpected results.

Related articles