Dynamic Programmable Content in Email Templates

If you need to implement more advanced behaviour in your email templates options related to this can be found in the styles section of the email editor:



Click STYLE here and scroll down you will find options for:

  • Custom CSS
  • Programmatic Syntax


Custom CSS

The custom CSS option is as it says an option to add some custom css to your template. If for example you have CSS for some mobile responsive behaviour like stacking images on mobile that appear in a row on Desktop it could be added here:



Programmatic Syntax

To enable programmatic syntax scroll down in STYLE and select enable for this:


You can then use a variety of syntax options in your email template to generate dynamic content. These options are based on the Twig template engine.

N.B. in addition to new capability there is one important change when enabling programmatic syntax. With this syntax off in standard personalisation mode if a personalisation param is missing for a user at send time an email will not send with error - not personalized. When you enable programmatic syntax missing params will render as blank. It is assumed you are handling such scenarios with conditional statements if required. This means if in programmatic mode you use basic syntax and don't handle missing params - "Hi {{ first_name }}",  will send as  "Hi," if param is missing. And to do a default fallback  {{ first_name || "there" }} becomes {{ first_name | default("there") }}.


If you can't see this option in your account it needs to to be activated.  If you are interested in getting started with programmable emails please contact your account manager and they can activate it for you or visit xtremepush.com to request a demo.

The programmatic capabilities are summarised below in sections:

  • Utility Functions
  • Loops
  • Conditional Statements


Utility Functions


If you need to generate the current day, date etc. programmatically in your content then you can add it to your template in the following way:

  • {{ "now" | date() }} will give:
    • Month day, year time e.g. January 18th, 2049 14:34 
  • {{ "now" | date("l, F jS") }} will give:
    • Day, Month Date e.g. Friday, January 18th
  • {{ "now"|date("l") }}
    • Day, e.g. Friday
  • {{ "now"|date("F") }}
    • Month e.g. January

The syntax can be used in the subject or the body for example - xtremepush newsletter for {{ "now" | date("l, F jS") }}.More detail on how the date format function works can be found here: http://php.net/manual/en/function.date.php  


If you have dynamic content such as names {{name}} that are a mix of lowercase bob and uppercase BOB but should be capitalised Bob you can clean it up using the capitalise function: 

{{name | capitalize}}


If you have dynamic content that you want to cut short or take a sub string from you can use the slice function. A common use case is truncating dynamic text, for example if you want to  cut short some text at 200 characters and add trailing dots you can use:


If Dynamic text was:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

it would become:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut a ..."

If your text contains html tags you should use striptags first to remove them so they don't get cut off and result in broken html.



For Loop for dynamic content e.g. recommendations 

For loops can be useful for generating a section of content that has a number of similar element repeated where the number of elements and content will vary for users. One example of this is a daily/weekly recommendation email linked to a recommender system for products, articles or some other form personalised content. These types of email will typically have a varying number of recommendations per user per day with many different variations in content. In this case a for loop can be used to build the personalised  recommendation portion of the email for each user. Below is an example where a table of recommendations is built using a for loop:

<p><!-- {% for entry in jobs %} --></p>
<hr noshade="noshade" color="#686868" width="100%" size="1" style="padding:0; margin:8px 0 8px 0; border:none; width:100%; height: 1px; color:#686868; background-color: #686868">
<table border="0" cellspacing="5" cellpadding="0" align="center" bgcolor="#ffffff"><tbody><tr><td width="45" rowspan="2" align="left" valign="centre"> <a href="{{entry.job.job_page_url}}" style="display:block; text-decoration:none;" data-pos="IC4AP9-t"> <img src="{{entry.brand.logo}}" alt="{{entry.brand.name}} logo" width="70" style="border-radius: 50%;"></a> </td> <td height="30" valign="bottom"><a href="{{entry.job.job_page_url}}" style="display:block; text-decoration:none;" data-pos="IDhr4HnC"><span style="color: #63c3d1; font-size: 18px; font-weight: bold; line-height: 1; vertical-align:middle;">{{entry.job.post_name }}</span></a></td></tr><tr><td valign="top" height="30"><a href="{{entry.job.job_page_url}}" style="display:block; text-decoration:none;" data-pos="eSPO0o6O"><span style="color: #686868; font-size:13px; font-weight: lighter;"><span style="color: #686868; font-size:13px; font-weight: lighter;">{{entry.brand.name}}{% if entry.brand.location %}, {{entry.brand.location}} {% endif %}</span></span></a></td> </tr></tbody></table>
<p><!-- {% endfor %} --></p>


The above example is from an API triggered template campaign and content like below is posted via API to target individual users with personalised recommendations. The job array can vary in size and content and is dynamically unpacked by template for loop. 


{"apptoken":"blah","id":blah,"target_by":"email","target":["blah@blah"],"params":{"user.first_name":"BOB","jobs":[{"job.post_name":"Job1","job.job_page_url":"https://example.com/jobs/view?1","brand.name":"Brand1","brand.logo":"https://example.com/logo1.jpg","brand.location":null},{"job.post_name":"Job2","job.job_page_url":"https://example.com/jobs/view?2","brand.name":"Brand2","brand.logo":"https://example.com/logo2.jpg""brand.location":null},{"job.post_name":"Job3","job.job_page_url":"https://example.com/jobs/view?3","brand.name":"Brand3","brand.logo":"https://example.com/logo3.jpg""brand.location":"Dublin, County Dublin, Ireland"},{"job.post_name":"Job4","job.job_page_url":"https://example.com/jobs/view?4","brand.name":"Brand4","brand.logo":"https://example.com/logo4.jpg""brand.location":"Dublin, Ireland"},{"job.post_name":"Job5","job.job_page_url":"https://example.com/jobs/view?5","brand.name":"Brand5","brand.logo":"https://example.com/logo5.jpg""brand.location": "Dublin,Ireland"}]}}

Conditional Statements

if/else for alternate content 

If else statements can be used to handle different scenarios related to dynamic content for example in the for loop in the previous example the dynamically added location information is not always present so an if statement is used to handle this. If the location is present it is added with a preceding comma if not neither the location or the comma is added:

{% if entry.brand.location %}, {{entry.brand.location}} {% endif %}

If else statements can be used to do regional variations in a single email if you have an appropriate region or geo attribute for your users for example:

{% if region == 'US' %} 
NY Address
{% elseif region == 'UK' %}
London Address
{% else %}
Dublin Address
{% endif %}

There are many other ways you can use this syntax to respond conditionally to dynamic content below is another example where links are being dynamically added and some end in a ? and some do not but we want to be able to add utm tracking to all the links. The inconsistency in link format is handled using if statements on the template side:

{% if '?' in entry.some.page_url %}<a href="{{entry.some.page_url}}&utm_source=xp&utm_medium=email&utm_campaign=blah" style="display:block; text-decoration:none;" data-pos="IC4AP9-t">{% else %}</a><a href="{{entry.some.page_url}}?utm_source=xp&utm_medium=email&utm_campaign=blah" style="display:block; text-decoration:none;" data-pos="IC4AP9-t">{% endif %}


Have more questions? Submit a request


Article is closed for comments.