Custom Email Templates in TFS 2010


Team Foundation Server 2010 can create custom alerts that fit almost any set of criteria you can come up with, but the emails that it generates are pretty generic, though informative.  Wouldn’t it be great if you were able to customize the information that was contained in them and maybe even spice them up a little bit with corporate branding?  With just a little bit of work, you can have these looking much better.

On your server that is housing the TFS 2010 Application Tier, all of the e-mail templates are contained in the same folder where TFS Job Agent was installed.  In my case, the files are located at:

C:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\TFSJobAgent\Transforms

There are many different templates here for different kinds of alerts, but for this example, we’ll concentrate on the normal Work Item alerts.  These are the ones that are used for alerts relating to Work Item changes, reassignment, and status updates, but there are others there for build alerts, checkins and the like.  These two files are:

  • WorkItemChangedEvent.xsl — This is the HTML version of the alert that is usually sent when the alert is triggered.
  • WorkItemChangedEvent.plaintextXsl — This is the plaintext version of the alert. 

Opening these files, you will see pretty standard XSL used the transform the TFS data into the alert e-mail.  For this example, let’s just add a header and create a link to the style sheet that I use for my custom process guidance to make sure the branding is identical across all communication with the end-users of the TFS instance.

So let’s modify the header and body of the e-mail to make things a bit more friendly…

<?xml version=“1.0” encoding=“UTF-8”?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform&#8221; version=”1.0″>
   <xsl:import href=“TeamFoundation.xsl”/>
   <!– Common TeamSystem elements –>
   <xsl:template match=“WorkItemChangedEvent”>
      <head>
      <!– Pull in the command style settings –>
      <xsl:call-template name=“style”>
      </xsl:call-template>
      <!– Link to the Company TFS Style Sheet –>
      <link href=http://processguidance.Company.com/Style/Content.css&#8221; type=“text/css” rel=“stylesheet” />
   </head>
<body>
      <!– Company Email header –>
   <div>
       <img height=“17” src=http://processguidance.Company.com/Images/EmailHeaderBar.png&#8221; />
      <br />
      <div>
         <div style=“float:left;”>
            <img alt=“Company Name” height=“40” src=http://processguidance.Company.com/Images/Company_logo.gif&#8221; width=“270” />
         </div>
      </div>
   </div>
<!– End Company Header–>

Now that we have some really basic markup in the header of the e-mail, our correspondence with the end-user will look much better.  Of course, you can dig a bit deeper to change the fields displayed in the alerts or add a footer.  Just make sure that you always have a backup of the original file and test test test!

Advertisements

6 thoughts on “Custom Email Templates in TFS 2010

    1. Hi Hugo,

      The style sheet that I am using here is tied to my company’s corporate branding as I think it is useful if all correspondence with end-users have the same branded look and feel.

      By default, the syles you have to override in a TFS message are:


      body, input, button
      {
      color: black;
      background-color: white;
      font-family: Verdana,Arial,Helvetica;
      font-size: x-small;
      }
      p
      {
      color: #666666;
      }
      h1
      {
      color: #666666;
      font-size: medium;
      }
      h2
      {
      color: black;
      }
      table
      {
      border-collapse: collapse;
      border-width: 0;
      border-spacing: 0;
      width: 90%;
      table-layout: auto;
      }
      pre
      {
      word-wrap: break-word;
      font-size: x-small;
      font-family: Verdana,Arial,Helvetica;
      display: inline;
      }
      table.WithBorder
      {
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      border-collapse: collapse;
      width: 90%;
      }
      TD
      {
      vertical-align: top;
      font-size: x-small;
      }
      TD.PropName
      {
      vertical-align: top;
      font-size: x-small;
      white-space: nowrap;
      background-color: #FFF;
      border-top: 1px solid #F1EFE2;
      }
      TD.PropValue
      {
      font-size: x-small;
      border-top: 1px dotted #F1EFE2;
      }
      TD.Col1Data
      {
      font-size: x-small;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      background: #F9F8F4;
      width: auto;
      }
      TD.ColData
      {
      font-size: x-small;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      }
      TD.ColDataXSmall
      {
      font-size: x-small;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      width: 5%;
      }
      TD.ColDataSmall
      {
      font-size: x-small;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      width: 10%;
      }
      TD.ColHeadingXSmall
      {
      background-color: #F1EFE2;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      font-size: x-small;
      width: 5%;
      }
      TD.ColHeadingSmall
      {
      background-color: #F1EFE2;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      font-size: x-small;
      width: 10%;
      }
      TD.ColHeadingMedium
      {
      background: #F1EFE2;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      font-size: x-small;
      width: 200px;
      }
      TD.ColHeading
      {
      font-size: x-small;
      border-style: solid;
      border-color: #F1EFE2;
      border-width: 1px;
      background: #F1EFE2;
      width: auto;
      }
      .Title
      {
      width:100%;
      font-size: medium;
      }
      .footer
      {
      width:100%;
      font-size: xx-small;
      }

      1. Hey, Nice article.. I just want to know if how can we integrate windiff or some other tool to see differences between the files checked into TFS.

        Thanks

      2. This is very useful, but it does raise two questions in my for me. First, how do we find the default styles that have to be overridden? I’ll need to use something like this for Checkin/CheckOut and possibly other events. Second, and this is more vague, where do the object names come from? By that I mean further down in the WorkItemChangedEvent.xsl file we see:

        Where do the element name “a” get specified, or the attribute name of “href”. What I’ve done is added a field to the ChangeRequest template and upon a WorkItemChangeEvent I want to be able to extract the current value of the field and add it to the email,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s