XSLT Personalization

Last Updated: 26/6/2024     Tags: personalization, personalisation, integration, data, subscriber
  • Switch Version
  • V5
  • V4

Overview

Taguchi templates, activities and tracked URLs can use replacement tags to insert personalized data like subscriber names, email addresses or custom fields. Tags consist of two hashes (##), a token, and two hashes.

Tag Generator

A simple personalization tag generator can be found here.


Replacement Tag Evaluation

Whether included in the template stylesheet or the activity content, replacement tags are are evaluated when the message is generated (email sent, SMS sent, or web page viewed) and use the current subscriber data. The only exception is tags included in URLs which have tracking enabled (by default, all email links); these tags are extracted by the tracking system and evaluated when the link is clicked, using the current subscriber data at that time.

For example, the link http://www.facebook.com/sharer.php?u=http%3A%2F%2F##config.hostname##%2Fpublic%2Fbroadcast%3Fsevt%3D##id## will automatically insert the system's hostname and the ID of the click event into a Facebook share link when the link is actually clicked, so that later activity can be traced back to individual sharers.

To force evaluation of link tracking tags at message generation time, an additional two hashes should be placed either side of the link (e.g. ####subscriber.custom.url####. Note that this will only work if the entire link URL is a replacement tag.

To render any stored HTML in the subscriber data or within the token modifiers, add an apostrophe after the first set of hash tags (e.g. ##!subscriber.custom.promo##). Warning:: Any invalid XHTML will cause the XSLT parser to not render the templates.

Token Modifiers

Basic tokens simply contain the name of the field to insert into the message; for example subscriber.firstname inserts the first name field of the current subscriber.

Tokens can include fallback values; these are specified using one or more pipe (|) characters, for instance subscriber.firstname|"Valued Customer" inserts the subscriber's first name if present, otherwise the text "Valued Customer". Multiple fallback values can be included if necessary.

Filtering and value transformation can be performed after default values have been substituted, by appending a semicolon (;) and filter expression to the token. The following filters are provided:

  • strftime(<format>): applies a date formatting operation, based on a format string as used in the C strftime standard library function.

  • capitalize(): capitalizes the first letter of each word in the value to be substituted.

  • lookup(<map>): uses the <dict> value (passed as a Python/JSON format object literal) as a lookup table, with the replacement expression as the key, and the value for that key being used as the substitution.

  • conditional(<if-true>, <if-false>): if the value to be substituted evaluates to true (i.e. is a non-empty string or a non-zero integer), the string <if-true> is substituted; if the value to be substituted evaluates to false (i.e. is an empty string, zero, or None/NULL) the <if-false> string will be substituted. The original value to be substituted can be used in the <if-true> string by including the tag %(val)s in the appropriate location.

For example:

  • subscriber.dob;strftime("%Y") takes the subscriber's date of birth, then passes it through the strftime filter which enables date and time values to be formatted;

  • subscriber.suburb;capitalize() capitalizes the first letter of each word in the subscriber's suburb;

  • subscriber.state;lookup({"VIC": "Victoria","NSW":"New South Wales","TAS":"Tasmania","QLD":"Queensland","WA":"Western Australia","SA":"South Australia","TAS":"Tasmania","ACT":"Australian Capital Territory","NT":"Northern Territory"}) would insert the full name of the subscriber's state, based on the abbreviated value in that field;

  • subscriber.firstname;conditional("Hi %(val)s!", "Hi!") would insert "Hi " if the subscriber's first name is present, otherwise the text "Hi!".

Template Conditionals

Subscriber data can also be used within the Transform Document to conditionally display content. This is useful for templates that need to be personalised based on the subscribers preferences.

For example to display content relating to a subscribers location:

<conditional test="context.get('subscriber.state')=='NSW'">
 <!--  NSW Content ->
</conditional>

<conditional test="context.get('subscriber.state')=='VIC'">
 <!--  VIC Content ->
</conditional>

Tracked URL Tags

Field Description
##id## subscriber event ID (of the clicked event)
##parent.id## parent subscriber event ID (of the sent or viewed event)
##subscriber.hash## the subscriber authentication hash (of the subscriber associated with this event)
##configuration.id## ID of the message configuration referenced by the parent event
##ref## the event ref (typically 'c' for Clicked or 'u' for Unsubscribed)
##campaign.id## ID of the campaign referenced by the parent event
##test## whether or not this is a test event; this is always inherited from the parent and cannot be overriden
##data## subscriber event data (for the viewed event)
##subscriber.id## ID of the associated subscriber
##subscriber.email## subscriber's email address
##subscriber.title## subscriber's title
##subscriber.firstname## subscriber's first name (auto-capitalized)
##subscriber.lastname## subscriber's last name (auto-capitalized)
##subscriber.address## subscriber's address
##subscriber.address2## subscriber's address line 2
##subscriber.address3## subscriber's address line 3
##subscriber.suburb## subscriber's suburb
##subscriber.state## subscriber's state
##subscriber.postcode## subscriber's postcode
##subscriber.country## subscriber's country
##subscriber.phone## subscriber's phone number
##subscriber.gender## subscriber's gender
##subscriber.dob## subscriber's date of birth
##subscriber.ref## subscriber's ref (aka external ID)
##subscriber.organization.id## subscriber's organization ID
##subscriber.hash## authentication hash for this subscriber
##subscriber.custom.<x>## subscriber custom fields

Activity and Template Tags

Field Description
##revision.id## ID of the activity revision being rendered
##configuration.id## ID of the message configuration
##ref## the event ref (typically 'v' for Viewed or 's' for Sent)
##campaign.id## ID of the campaign to which this event should be credited (preset to the campaign ID of the activity)
##activity.id## ID of the activity (the xml_content_id of the revision)
##test## whether or not this is a test event; if there is a parent event, this will be inherited from it
##data## subscriber event data (for the viewed event)
##subscriber.id## ID of the associated subscriber
##subscriber.email## subscriber's email address
##subscriber.title## subscriber's title
##subscriber.firstname## subscriber's first name (auto-capitalized)
##subscriber.lastname## subscriber's last name (auto-capitalized)
##subscriber.address## subscriber's address
##subscriber.address2## subscriber's address line 2
##subscriber.address3## subscriber's address line 3
##subscriber.suburb## subscriber's suburb
##subscriber.state## subscriber's state
##subscriber.postcode## subscriber's postcode
##subscriber.country## subscriber's country
##subscriber.phone## subscriber's phone number
##subscriber.gender## subscriber's gender
##subscriber.dob## subscriber's date of birth
##subscriber.ref## subscriber's ref (aka external ID)
##subscriber.organization.id## subscriber's organization ID
##subscriber.hash## authentication hash for this subscriber
##subscriber.custom.<x>## subscriber custom fields

Note that it is not possible to access annotations of an event relating to messages being sent (via base.message implementers) since base.message.log_sent doesn't expose the annotation parameter, and as a result there's no way to add annotations to a send event except through APIs used after the message is actually sent (and therefore not relevant to the scripts generating the message).