ResourcesKnowledge Base

Including and processing

The templating language of Mailkit allows users to create very complex templates for hyper-personalized content. Such complex templates could easily become too difficult to understand. To avoid this you can break down your templates into smaller files. These files can be shared across multiple templates making your code reusable. This speeds up maintenance and development of new templates.

We know this all too well - as your templates are getting smarter, readability becomes lower. At some point you are just wondering how did you get here. We know because we have built quite a few templates for our clients ourselves. The solution is a simple as breaking down the content into smaller sections and including these into the template.

As you already know the template can contain multiple different template file types including the so called Blank files. These files can be created in both shared templates as well as within a specific template. The main difference between the two is, that the Shared templates files can be used as an include from any template. Now you are probably thinking headers, footers - the most obvious candidates but it goes further than that.

Of course you could limit your includes to header and footer but how much would that help? Includes do not have to be the simple parts that are being reused in your templates. Includes can do some magic for you and help you really save a lot of time. Consider the following - how many times do you use a call to action button in your template? And what if you considered ANY button?

Before we start with practical examples we should consider the order in which template files are included/processed. First the referenced template file is looked-up within the current template used. If not found the referenced template files is looked-up in Shared templates. If template file is not found in any of the two locations the template will return an error. It is not possible to reference files stored in other templates. Remember that in case of template files with same name stored in template as well as in shared templates the file in the template takes precedence.

Including files

Let’s look at a practical example of such an html button saved as button.html:

<div><!--[if mso]>
  <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
  href="" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" stroke="f"
      <a href="" style="background-color:#b2102f;border-radius:4px;color:#ffffff;
      text-decoration:none;width:200px;-webkit-text-size-adjust:none;">Click me!</a>
  <!--[if mso]>

You could easily include this button in your template by using the include command:

[% INCLUDE "button.html" -%]

Which would include the code from button.html in your template. That could help you make your template more readable but it won’t be very effictive as it would not help much with increasing efficiency.

To make your includes really worth it you need to make them work with data variables instead of hard coded values. We can easily see a couple of values that could benefit from being variable - button text, url & color, text color & size. Let’s enhance our block to use variables:

<div><!--[if mso]>
  <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="[% url -%]"
  style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" stroke="f" fillcolor="#[% bgcolor -%]">
      <a href="[% url -%]" style="background-color:#[% bgcolor -%];border-radius:4px;color:#[% text_color -%];
      display:inline-block;font-family:sans-serif;font-size:[% text_size -%];font-weight:bold;line-height:40px;
      text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;">[% text -%]</a>
  <!--[if mso]>

Now we can include this button and pass the parameters to the included file:

[% INCLUDE "button.html", text='Cool CTA!', url='',
bgcolor='ff0000', text_color='ffffff', text_size='14px' -%]

You may want to add some defaults to the top of the button.html file to make sure it displays correctly even when you don’t pass all the parameters:

[% IF !text; text='Click me!'; END -%]
[% IF !url; url='#'; END -%]
[% IF !bgcolor; bgcolor='990000'; END -%]
[% IF !text_color; text_color='ffffff'; END -%]
[% IF !text_size; text_size='13px'; END -%]

The possibilities of passing data to included files are nearly unlimited and the included file can access any existing variables from the template that initiated the include.

Let’s look at an example of how this could help us with more advanced templating. For our sample newsletter we want to list random products from a data source. We are covering working with data in a separate article. Let’s just start by creating a very simple product block file product.html:

    <td valign="top">
      <a href="[% link -%]" target="_blank"><img src="[% uri -%]" width="200" border="0" alt="[% title -%]"></a>
    <td valign="top">
      <h3>[% title -%]</h3>
      <p>[% description -%]</p>
      [% INCLUDE "button.html", text=price, url=link -%]

As you can see this file is using variables to display content and in addition includes the button and passes the price and url as variables to the button.html file. Since we have set some defaults in the button.html file, the text size, color and background color will have the default values.

Now that you have the product block designed you can reuse it across all your templates. You could use the data from events to build an abandoned cart email or use data acquired from the product feed to build a newsletter. We will use a similar example as described in the working with data article:

[% USE dbh_sql = DBI (dbh = shared.DBI_DS_SQL_PRODUCTS) %]
[% query_items = dbh_sql.prepare('SELECT * FROM ds_3223_products
   WHERE `availability`="in stock" ORDER BY RAND() LIMIT 5') %]
[% items=query_items.execute() -%]
[% IF items.size == 0 -%]
    [% items=query_items.execute('%') -%]
[% END -%]
[% FOREACH items -%]
  <div>[% INCLUDE "product.html" -%]</div>
[% END -%]

And you can expect an output similar to this:

Use of INCLUDE takes on a whole different meaning when used in Drag & Drop template blocks. When INCLUDE is used in a block it will serve dynamic content from the included file. Think of it as a combination of the smart templating with Drag & Drop user friendliness. It allows you to have blocks, that will serve dynamic content personalized for each recipient.

Processing files

Processing instead of including brings a whole different set of advantages. Processed files are not just put in place as includes are, but remain available throughout the whole template. This means that you can easily reuse the the whole file or parts of it whenever you need.

Let’s look at our example with the products coming from the feed. The output of the price in the button could clearly have a nicer formatting and we might as well want to display the price including VAT. We could do it within the include but since this is something that can be reused in multiple places we will process it in a block.

Start by creating a new file caled functions.html with the following content:

[% USE Number.Format(THOUSANDS_SEP => '&nbsp;', DECIMAL_POINT => ',', DECIMAL_DIGITS => '2') -%]
[% BLOCK price_data -%]
    [% price = price FILTER remove(' CZK') -%]
    [% price_vat = price * 1.21 | format_number(0) -%]
    [% price = price | format_number -%]
    [% price = price _ ',-' -%]
[% END -%]

And we add the processing of functions.html to the top of our main template before all the data is beind used:

[% PROCESS "functions.html" -%]

Now that the file is processed we have a function called price_data available at any time to do our magic with formatting the price and calculating the price including VAT. Now we will call that function from product.html by adding a simple line:

[% PROCESS price_data -%]

This will apply the formatting to the price of all individual products in the output and provide us with a formatted price as well as a variable with the price including VAT. We can easily add that number to the output of product.html just below the include of the button:

<p><small>Price incl. VAT: [% price_vat -%],-</small></p>

Giving us a nicely formatted output:

In the above example we know the name of the variables and therefore we are not passing them to the block. We could easily pass variables as a parameter or we could pass multiple variables and have the block perform the operations and return the result.

Use of PROCESS has a different meaning when used in Drag & Drop template blocks. When PROCESS is used in a block it will generate the dynamic content from the PROCESSED file at the time the block is dropped into the message. Imagine a block, that dynamically generates its content when you put it to your message so you can fine-tune it's content. Instead of manually selecting 3 products every single time you can use a PROCESS block to fetch the top 3 new products from a data source and adjust their descriptions and prices ni the message before sending it.

There are many ways to use templates to help you optimize and streamline your campaigns - whether it’s simple data formatting, reusing template blocks or generating dynamic content. Feel free to contact our customer support for assistance on coding templates and their advanced features