In JIRA 6.1-OD3, the email templates for JIRA have changed to sport a new ADG-compliant look and feel.
The parts of JIRA's emails that have changed most significantly are:
The full guidelines for ADG-compliant emails are forthcoming and will be published to developer.atlassian.com/design in the coming months.
The JIRA email templates are now run through a utility called Botocss. Botocss applies CSS rules as inline styles to a given HTML input.
This has enabled the separation of the CSS styling of emails from the templates, significantly simplifying the task of achieving a consistent look and feel for emails.
If you're tired of handcrafting and double-checking every inline style, this should be a breath of fresh air for you.
Applying the JIRA email CSS to its email templates is achieved through the BotocssMailUtility#applyStyles
method.
Use of Botocss is opt-in - you may either use BotocssMailUtility
to apply JIRA's email CSS, invoke Botocss#inject
manually, or continue to code your email styles inline in your templates.
For reference, the JIRA email CSS is stored in the following files and applied in the following order:
jira-components/jira-core/src/main/resources/templates/email/css/aui-styles.css
jira-components/jira-core/src/main/resources/templates/email/css/all-clients.css
jira-components/jira-core/src/main/resources/templates/email/css/wiki-renderer.css
jira-components/jira-core/src/main/resources/templates/email/css/jira-styles.css
The email templates are still velocity templates, and are located in the same folder they were placed in for JIRA 4.4.
However, the structure of each email template has changed, along with the semantics of some of the helper templates such as header.vm
and footer.vm
.
Here is a comparison of some of the old and new templates:
OLD
1 2e#disable_html_escaping() #parse("templates/email/html/includes/emailconstants.vm") #parse("templates/email/html/includes/header.vm") <tr valign="top"> <td id="email-banner" style="padding:32px 32px 0 32px;"> #if ($changelogauthor) #set ($changelogauthorLink = "#authorlinkkey($changelogauthor.key $linkstyle)") #else #set ($changelogauthorLink = "#authorlinkname($remoteUser.name $linkstyle)") #end #set ($issueType = $issue.getIssueTypeObject()) #set ($issueLink = "#renderIcon(${issueType.iconUrlHtml} ${issueType.getNameTranslation($i18n)}) <a style='color:${textLinkColour};text-decoration:none;' href='${baseurl}/browse/${issue.getKey()}'>$issue.getKey()</a>") #emailbanner($changelogauthor "email.event.activity.updated" $changelogauthorLink $issueLink "") </td> </tr> #if ($changelog || $comment) <tr valign="top"> <td id="email-fields" style="padding:0 32px 32px 32px;"> <table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%"> <tr valign="top"> <td id="email-gutter" style="width:64px;white-space:nowrap;"></td> <td> <table border="0" cellpadding="0" cellspacing="0" width="100%"> #parse("templates/email/html/includes/fields/comment.vm") #parse("templates/email/html/includes/fields/changelog.vm") </table> </td> </tr> </table> </td> </tr> #end #parse("templates/email/html/includes/footer.vm")
NEW
1 2#disable_html_escaping() #defaultMailHeader('jira.email.title.activity.updated', $changelogauthor) #if ($comment) #parse('templates/email/html/includes/patterns/comment-top.vm') #end #rowWrapperNormal("#parse('templates/email/html/includes/patterns/issue-title.vm')") #if ($changelog && $changelogItemIssueDescription) #rowWrapperNormal("#parse('templates/email/html/includes/fields/changelog.vm')" '' 'wrapper-special-margin') #elseif ($changelog) #rowWrapperNormal("#parse('templates/email/html/includes/fields/changelog.vm')") #end #parse('templates/email/html/includes/changelog-issue-description.vm') #set ($commentActionBody="#parse('templates/email/html/includes/patterns/comment-action.vm')") #rowWrapperNormal($commentActionBody) #parse('templates/email/html/includes/footer.vm')
OLD
1 2#disable_html_escaping() #parse("templates/email/html/includes/emailconstants.vm") #parse("templates/email/html/includes/header.vm") <tr valign="top"> <td id="email-banner" style="padding:32px 32px 0 32px;"> #if ($changelogauthor) #set ($changelogauthorLink = "#authorlinkkey($changelogauthor.key $linkstyle)") #else #set ($changelogauthorLink = "#authorlinkname($remoteUser.name $linkstyle)") #end #set ($issueType = $issue.getIssueTypeObject()) #set ($issueLink = "#renderIcon(${issueType.iconUrlHtml} ${issueType.getNameTranslation($i18n)}) <a style='color:${textLinkColour};text-decoration:none;' href='${baseurl}/browse/${issue.getKey()}'>$issue.getKey()</a>") #emailbanner($changelogauthor "email.event.activity.comment.edited" $changelogauthorLink $issueLink "") </td> </tr> #if ($comment) <tr valign="top"> <td id="email-fields" style="padding:0 32px 32px 32px;"> <table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%"> <tr valign="top"> <td id="email-gutter" style="width:64px;white-space:nowrap;"></td> <td> <table border="0" cellpadding="0" cellspacing="0" width="100%"> #parse('templates/email/html/includes/fields/comment.vm') </table> </td> </tr> </table> </td> </tr> #end #parse("templates/email/html/includes/footer.vm")
NEW
1 2#disable_html_escaping() #defaultMailHeader('email.event.activity.comment.edited.on.issue', $changelogauthorLink) #set ($commentTopPatternClasses = 'comment-top-special-margin') #set ($htmlComment = $!diffutils.diff($originalcomment.body, "background-color:${auiErrorBackgroundColour};text-decoration:line-through;", $comment.body, "background-color:${auiSuccessBackgroundColour};")) #parse('templates/email/html/includes/patterns/comment-top.vm') #set ($issueTitleBody="#parse('templates/email/html/includes/patterns/issue-title.vm')") #rowWrapperNormal($issueTitleBody) #set ($commentActionBody="#parse('templates/email/html/includes/patterns/comment-action.vm')") #rowWrapperNormal($commentActionBody) #parse('templates/email/html/includes/footer.vm')
OLD
1 2#disable_html_escaping() #parse("templates/email/html/includes/header.vm") <tr valign="top"> <td id="email-banner" style="padding:32px 32px 0 32px;"> #set ($authorLink = "#authorlinkname($remoteUser.name $linkstyle)") #set ($issueType = $issue.getIssueTypeObject()) #set ($issueLink = "#renderIcon(${issueType.iconUrlHtml} ${issueType.getNameTranslation($i18n)}) <a style='color:${textLinkColour};text-decoration:none;' href='${baseurl}/browse/${issue.getKey()}'>$issue.getKey()</a>") #emailbanner($remoteUser "jira.mentions.email.header" $authorLink $issueLink '') </td> </tr> #if ($comment) <tr valign="top"> <td id="email-fields" style="padding:0 32px 32px 32px;"> <table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%"> <tr valign="top"> <td id="email-gutter" style="width:64px;white-space:nowrap;"></td> <td> <table border="0" cellpadding="0" cellspacing="0" width="100%"> #parse("templates/email/html/includes/fields/comment.vm") #parse("templates/email/html/includes/mention-actions.vm") </table> </td> </tr> </table> </td> </tr> #end #parse("templates/email/html/includes/footer.vm")
NEW
1 2#disable_html_escaping() #set($extraFooterContent = "${i18n.getText('jira.mentions.email.hint')}: ${i18n.getText('jira.mentions.email.hint.message')}") #genericChangelogMailWithComment('jira.email.title.mention')
header.vm
, emailconstants.vm
)With the move of the notification actor's details outside of the email chrome, header.vm
has taken on a drastically different meaning than it had in JIRA 5.
You should never need to invoke header.vm
yourself.
In the simplest case - rendering the actor details and the email's title - you only need to call:
1 2#defaultMailHeader('my.email.i18n.key.title', $notificationActorUserObject)
If you need to pass additional data to your header, use the following:
1 2#defaultMailHeaderWithParam('my.email.i18n.key.with.a.variable.title', $notificationActorUserObject, $variableValueInHtml)
It should be very rare to need to invoke header.vm
yourself. If you do decide to, ensure you #set
the following variables before calling #parse
for header.vm
:
#parse('templates/email/html/includes/emailconstants.vm')
$actionerUser
= the user who triggered the email notification$authorLink
= a rendered HTML link to the user that includes their avatar (typically, the output of the #authorlinkname
macro)$headerTitle
= the rendered HTML for the email's title. Typically this will be the result of the $i18n.getText() call for your email's title.There are several ways you can render content in the body of your email.
There is a new macro - #textParagraph
- that outputs HTML passed to it in a paragraph within the email's body.
For example, this:
1 2#textParagraph("$i18n.getText('my.important.message','<strong>','</strong>')")
Renders the following HTML content (before Botocss is invoked):
1 2<table class='text-paragraph-pattern' cellspacing='0' cellpadding='0' border='0' width='100%'> <tr> <td class='text-paragraph-pattern-container mobile-resize-text'> This message is <strong>super</strong> important. </td> </tr> </table>
You can also invoke the text-paragraph.vm
template manually:
1 2#set ($textParagraph = "$i18n.getText('my.important.message','<strong>','</strong>')") #parse('templates/email/html/includes/patterns/text-paragraph.vm')
The first approach is to pass some rendered HTML to the #rowWrapperNormal
macro:
1 2#set ($issueTitleBody="#parse('templates/email/html/includes/patterns/issue-title.vm')") #rowWrapperNormal($issueTitleBody) #rowWrapperNormal("#parse('templates/email/html/includes/patterns/comment-action.vm')")
Note the use of double quotes around the calls to #parse
, which ensure the nested template is evaluated at that point and stored as a String value.
The second approach is to use the two macros - #rowWrapperNormalBegin
and #rowWrapperNormalEnd
- within your template, which will output the appropriate markup to render the structure around your content:
1 2#rowWrapperNormalBegin() #textParagraph($i18n.getText('template.user.forgotusername.requestedusernames')) #rowWrapperNormalEnd()
All three 'rowWrapperNormal' macros accept two additional optional parameters: an ID to attach to the row in the email, and any additional classes to add to the element. Both are useful to hook CSS styles to the email elements.
1 2#rowWrapperNormalBegin('more-info-section' 'wrapper-special-margin my-custom-css-class') <p>Hi thar!</p> #rowWrapperNormalEnd() #set($textParagraph = 'Lorum ipsum sit dolor amet') #rowWrapperNormal("#parse('templates/email/html/includes/patterns/text-paragraph.vm')", '', 'issue-description-container')
footer.vm
)This is unchanged from JIRA 4 or 5. Simply place #parse('templates/email/html/includes/footer.vm')
at the end of your email template file.
Rate this page: