![](/_scripts/dojo_dist/jazz/cs/graphics/Library/bttn_article52.gif)
Creating an email template for Rational Team Concert
Filip Wieladek, IBM
Last Update: May 25, 2012
Build Basis: Rational Team Concert 4.0
Introduction
Rational Team Concert 4.0 introduces customizable email templates which enable you to customize the notification emails which are sent after certain events take place in the system. This article gives an introduction into the customization options. After reading the article you should be able to:
- Understand how the default email templates work
- Write your own email templates
Email Template Configuration
In Rational Team Concert 4.0 the following email notifications can be customized:
- Approvals – Emails sent to users when they get added to Approvals
- Message At @Me – Emails sent to users when they are mentioned in work items (e.g. @bill)
- Work Item Change Notification – Emails sent to users when a work item changes to which they are subscribed to
The configuration options can be found in both the Web client as well as in the Eclipse client. In the Web client, you can find the configuration option under Manage Project Area > Mail Templates while in the Eclipse client you can find it under Open Project Area > Process Configuration > Project Configuration > Configuration Data > Work Items > E-mail Templates. The functionality in the Web and Eclipse client is identical, with the exception that the Eclipse client can generate the plain text template from the HTML template. Figure 1 depicts the configuration dialog which allows you to change the title and the body of the email to be sent.
Once you are done customizing an email notification, you probably want to test the template to see what the result looks like. One way would be to trigger the actual event (e.g. by adding a comment with an @Me mention) and then wait for the notification email to arrive. That would be very time consuming, especially while fine tuning the template. Fortunately, the configuration page allows you to test a template directly. The test dialog (see Figure 2) can be found by pressing the Test Template button.
In the test dialog you can edit the template as well as select the context (user, relation, work item, etc.) for a preview. Pressing the Generate button will generate a preview of the email with the chosen context. The Apply button will save the modified subject and body into the template and the Cancel button will discard all your changes since the last time Apply was pressed.
It is time to customize the actual content of the notification email. Select the Work Item Change Notification email type and enter the following values:
Work Item Change NotificationBody
<html> <body> A Work Item to which you are subscribed to has changed. </body> </html>
Test the template. Notice that the resulting email content is independent of your context selection (e.g. user or work item). Obviously, an email notification like this is not very useful as it does not provide any contextual information about the event which triggered the notification.
Template Language
As we can see, static text is not sufficient to have useful email notifications. For that reason, Rational Team Concert uses the Velocity Template Language (VTL) to provide support for dynamic values. This article provides only a brief introduction into the Velocity Template Language, for a detailed tutorial about VLT consult the Velocity Template User Guide.
The Velocity Template Language works by using variables and references to provide dynamic content. These begin with a ‘$’ and are optionally surrounded by curly brackets. For instance, if you want to access the message (from the Message @Me notification) you can use ${message}
, which will be substituted by the actual message content at runtime. You can also access any valid quantified property, such as ${workitem.identifier}
which would substitute the expression for the id of the workitem.
Every reference in VTL is typed, which means that the available properties depend on the type of the reference. The listing of all available variable types and their properties can be found on the Email Templates Wiki.
Available variables
References allow for adding dynamic content to the email templates, but how can one know which references are valid from within the email templates? The context for every email notification type varies slightly. The following tables show which references are valid in which template.
Approvals
Variable | Description |
---|---|
${recipient} : Contributor | Recipient of the mail |
${workitem} : WorkItem | Work item to which the approval belongs |
${approvalTitle} : Text | Title of the approval. Should be used in the mail subject. |
${approvalDescription} : Text | Description of the approval. Should be used in the mail body. |
Message At @Me
Variable | Description |
---|---|
${recipient} : Contributor | Recipient of the mail |
${recipientRelation} : ContributorRelation | Relation the recipient has to the work item (e.g. owner, subscriber, …) |
${workitem} : WorkItem | Work item in which somebody was @mentioned |
${message} : Text | Message |
Work Item Changed Notification
Variable | Description |
---|---|
${recipient} : Contributor | Recipient of the mail |
${recipientRelation} : ContributorRelation | Relation the recipient has to the work item (e.g. owner, subscriber, …) |
${workitem} : WorkItem | Work item that was changed |
${change} : WorkItemChange | Change on the work item |
As previously mentioned, the major disadvantage of Example 1 is the lack of contextual information provided in the email. With the use of VTL and references it is now possible to add dynamic information.
Work Item Change Notification: [Work Item ${workItem.identifier}] ${workItem.title}Body
<html> <body> ID: <a href="${workItem.URL}">${workItem.identifier}</a><br/> Type: ${workItem.type}<br/> Summary: <a href="${workItem.URL}">${workItem.title}</a><br/> Filed Against: ${workItem.categoryName}<br/> State: ${workItem.state}<br/><br/> <b>${change.contributor.name}</b> changed on ${change.date.fullDate} at ${change.date.fullTime}: <br/> ${change.description} <br/><br/><hr/> You are receiving this mail because you are ${recipientRelation.description} ${recipientRelation.abbreviation} of this work item. </body> </html>
The resulting email from the template in Example 2 is shown below.
Type: Defect
Summary: CompositeRunner.filter incorrect if child throws NoTestsRema
Filed Against: JUnit
State: New
Bill Cassaveli changed on :
Status: Resolved –> Verified
You are receiving this mail because you are owner [o] of this work item.
The template uses references to provide context information in the email. The ${workItem.identifier}
reference is used to access the identifier of the work item which triggered the notification. ${workItem.URL}
, ${workItem.title}
, ${workItem.categoryName}
are all used to access attributes from the work item. From the Email Templates Wiki it is known that it is possible to access the ${recipientRelation}
and ${change}
variables along with their properties.
Note: It is not possible to specify the format of the date returned by ${change.date.fullDate}
. The format is determined by the locale of the server running Rational Team Concert.
Directives
In addition to dynamic substitution of references, one would like to be able to conditionally include or exclude certain information. Consider the case where you want to change the colour of a value depending on whether a work item is resolved. Variable substitution alone is not sufficient for that purpose. The Velocity Template Language provides basic scripting functionality with directives. This article briefly describes three directives which can be used:
- #if – can be used for conditional execution of certain parts of the template
- #set – can be used for temporary storage of values
- #foreach – can be used for iterating over lists
#if
The #if
directive allows for the conditional inclusion of text based on a condition. The directive begins with an #if
clause followed by a condition and the text to include. It ends with an #end
clause. Optionally, you can also use an #else
clause to include text in the case when the condition is false.
For example, if you want to display the state field in green if the state is resolved, you can do the following:
State: #if( ${workItem.resolution} == "" ) <span style="color: red"> #else <span style="color: green"> #end ${workItem.state}</span>
This part of a template changes the colour of the state value text. If no resolution text exists, then the work item is not resolved. We can use this fact to create a span with a style of {color : red}
. This causes the state field to be shown in a red color. Conversely, if the work item contains a resolution, the template will show the value in green.
#set
The #set
directive is used for setting values to variables or references. The assignment occurs inside brackets as in the example below:
#set( $result="success" )
The directive can be used to simplify the template and remove duplicated code. In the Example 3, a usage of the #if
directive is shown. It is now possible to simplify the example with the help of the #set
directive:
State: #if( ${workItem.resolution} == "" ) #set($color="red") #else #set($color="green") #end <span style="color: $color">${workItem.state}</span>
#set
directive#foreach
The #foreach
directive allows us to iterate over a list of items. Its syntax is very similar to the previous directives:
#foreach( $i in $list ) <li>${i}</li> #end
This snippet will create a <li>
element for every item in the list. In the email template example, we can use the #foreach
directive to display the first five comments
#foreach ( $c in ${workItem.comments} ) #if ( ${velocityCount} <= 5 ) <hr/> comment ${c.identifier} ( by ${c.creator} on ${c.created} ) <br/> ${c.description} #end #end
Example 5 uses the built in ${velocityCount}
variable, which indicates the current iteration count. In Rational Team Concert this variable always starts from 1. The comments variable type provides special properties to make it easier to write useful templates. Consider the case of displaying the last five comments (instead of the first 5). Example 5 is then rewritten in the following way:
#foreach ( $c in ${workItem.comments.mostRecentFirst.takeFirst(5)} ) <hr/> comment ${c.identifier} ( by ${c.creator} on ${c.created} ) <br/> ${c.description} #end
The mostRecentFirst
property of the CommentList provides the comments sorted from the newest to the oldest. Additionally, the takeFirst(x)
property is used to returns the first x number of items.
Raw vs. Formatted
Raw and formatted properties indicate whether special characters in text content are escaped or not. All of the variables types (with the exception of Boolean) support the raw and formatted properties. Their behaviour depends on whether the current template is used for a HTML or plain text mail. If the current template is used in an HTML mail, and the attribute is a string such as a URL, the formatted method will make sure that all characters with special meaning in HTML (e.g. ‘<‘, ‘&’) are escaped. It is occasionally necessary to use the raw property, which returns an unmodified representation of the attribute. For example, suppose we have an HTML template containing an IF-statement. The statement
#if({message} == "<test>") [...] #end
will not work as expected because ‘<‘ and ‘>’ are escaped. The correct statement looks like this
#if({message.raw} == "<test>") [...] #end
Note The formatted property is used by default, which means that ${message}
is the same as ${message.formatted}
.
Putting it all together
Example 7 is a compilation of previous code snippets into a powerful email template. The template makes extensive use of references, provides information depending on certain conditions, and iterates over a list.
#if( ${workItem.resolution} == "" ) #set($color="red") #else #set($color="green") #end <html> <body> ID: <a href="${workItem.URL}">${workItem.identifier}</a><br/> Type: ${workItem.type}<br/> Summary: <a href="${workItem.URL}">${workItem.title}</a><br/> Filed Against: ${workItem.categoryName}<br/> State: <span style="color: $color">${workItem.state}</span><br/><br/> <b>${change.contributor.name}</b> changed on ${change.date.fullDate} at ${change.date.fullTime}: <br/> ${change.description} <br/><br/> #if ( ${workItem.comments.size()} > 0 ) The last five comments in the work item are: #foreach ( $c in ${workItem.comments.mostRecentFirst.takeFirst(5)} ) <hr/> comment ${c.identifier} ( by ${c.creator} on ${c.created} ) <br/> ${c.description} #end #else There are no comments in the work items #end <br/><br/><hr/> You are receiving this mail because you are ${recipientRelation.description} ${recipientRelation.abbreviation} of this work item. </body> </html>
The resulting body of the email notification follows.
Type: Defect
Summary: CompositeRunner.filter incorrect if child throws NoTestsRema
Filed Against: JUnit
State: New
Bill Cassaveli changed on :
Status: Resolved –> Verified
The last five comments in the work item are:
comment 2 ( by ADMIN on Tuesday, May 29, 2012 )
Have you already implemented it?
It would seem that the NoTestsRemainException is still being thrown.
comment 1 ( by ADMIN on Tuesday, May 29, 2012 )
Yes, you are correct
You are receiving this mail because you are owner [o] of this work item.
Limitations
At the time of writing of this article, the template engine used in Rational Team Concert has some limitations.
The Velocity Template Language supports the directives #include
and #parse
. These have been disabled due to security implications. It is also not clear where the included and parsed files would be stored as the templates are stored in the process specification itself.
VTL allows for setting variables and properties with the #set
directive. It is however not possible to set the attributes of work items over templates. For example, #set ( ${workItem.title} = "..." )
will not change the summary of the work item.
It is possible to acquire the values of custom attributes using the ${workItem.get(...)}
. Unless the attribute type is one of the specified supported types, the return type will always be a text type. For instance, the value returned for an attribute with an enumeration type will be the label and of type Text. Similarly an attribute of type Enumeration List can be accessed but the returning value will be be a comma separated string.
Currently it is also not possible to examine the changes in the Work Item Change Notification. All you receive is the ${change}
variable, but you will not be able to check for exact changes. For example, it is not possible to check if a work item was resolved with this change. This requires knowledge of what changes exactly happened.
Rational Team Concert uses the Velocity Template Engine version 1.5. Features which were implemented in later versions will not work.
Finally, it is important to note that this is not a mechanism for conditional notifications. This means that you cannot use work item templates to determine to who a notification is being sent out. These templates can only be used to customize the content of the notifications and not the behaviour of the notification system.
Conclusion
This article has given you a brief introduction into the customization options, along with the limitations, of email templates. After reading the article you should now be confident enough to create an own custom email notification which is specifically tailored to your workflow.Further Reading
The Email Templates Wiki contains a detailed reference on available context variables and available types.
The Velocity Template User Guide contains a detailed user guide and tutorial on the Velocity Template Language.
About the Authors
The authors are developers in the Tracking and Planning team working on the Work Item component of Rational Team Concert. For additional information about the topic presented in the article add your comments or questions directly in the discussion part, or visit our Jazz.net Forum.
Copyright © 2012 IBM Corporation