FeedOtter Logo Standard

How to Create Custom Email Templates for FeedOtter

Building data-driven emails using the FeedOtter template system.
Bottom Swoop SVG


This guide will walk you through the creation of a basic, custom HTML email template that works with FeedOtter.  This guide will focus on creating the technical elements of the data-driven email.  You can apply the lessons learned here to your own HTML email creation to create custom, data-driven emails that are compatible with FeedOtter's automated and curated email features.

About FeedOtter's Token Language

Like many other email softwares FeedOtter has a token or merge variable language.  Using any of the following tokens in your FeedOtter HTML email will result in data being displayed in place of the token object.

There are several different kinds of tokens:

Campaign Tokens:
Used to display data related to the FeedOtter campaign object such as Send Date or Campaign Name.

Post Loop Tokens:
These are tokens that relate to your RSS content such as post title, description, url, and author.

UI Tokens:
These are special tokens that allow you to interact with the FeedOtter "edit" UI.  Examples include: primary color, button color, and heading text.  If you are coding an email from scratch we recommend using Custom Tokens rather than UI tokens as they offer more flexibility.

Custom Tokens:
These are tokens defined in the email template file.  You can create any number custom tokens to make parts of your email editing from the FeedOtter edit UI.  Customers use these to allow for custom image uploads, text and headline updates and more.  

Campaign Tokens

These tokens are used to display properties from the parent FeedOtter campaign object.
Merge CodeDescription
[[feedotter.campaign_name]]The name of your campaign as provided during the wizard process
[[feedotter.send_date]]A text string date that your email is generated/sent. By default the date is formatted as: Tuesday, November 15 2016
[[feedotter.send_date_object]]A date object that can be used for advanced formatting such as [[feedotter.send_date_object | date("Hi m/d/Y", "Europe/Paris")]] Good resources for date building are: PHP date function and PHP date generator. 
[[feedotter.campaign_from_name]]The FROM NAME value as provided during the campaign wizard process
[[feedotter.campaign_from_email]]The FROM EMAIL value as provided during the campaign wizard process
[[feedotter.campaign_reply_email]]The REPLY EMAIL address as provided during the campaign wizard process
[[feedotter.preheader_text]]Special text block designed for an email preheader. This includes the title of the first post and the first 100 characters of the first post text.

Post Loop Tokens

Merge CodeDescription
[[post.post_title]]The title of a blog post. Use [[post.post_title | truncate(60,true,”…”)]] to truncate the title to 60 characters of length.
[[post.post_description]]The full content (including HTML if present) as available in the node of an RSS feed
[[post.post_description_text]]A text-only version of the node from the RSS feed. You can truncate this field to 200 characters like this: [[post.post_description_text | truncate(200,true,”…”)]]
[[post.post_excerpt]]An automatically created snippet based on the RSS fields. Our system looks for the best option and creates this. This field may include HTML if present
[[post.post_excerpt_text]]Same as post_excerpt with HTML stripped. [[post.post_excerpt_text | truncate(200,true,”…”)]]
[[post.post_url]]The url of a blog post
[[post.post_author]]The author name of a blog post
[[post.post_date]]The publish date of a blog post. This field can be formatted using [[post.post_date | date("F d")]]
[[post.post_source]]The name of the source blog of a blog post
[[post.image_url]]The best image to represent a blog post as chosen by our alogrithm. Use the following [[post.image_url | resize(200,300)]] to use our magic image cropping API
[[post.post_timeToRead]]Displays an estimated article read time based on description field of RSS. “Read Time: 2 minutes” etc..

The publish date of a blog post.
This field can be formatted using [[post.post_date | date("F d")]]

For details on how to format dates please visit: https://www.php.net/manual/en/function.date.php

UI Tokens

These merge codes correspond to properties that can be customized from the FeedOtter Customize interface.

Merge CodeDescription
[[feedotter.primary_color]]The color(hex) selected as primary color in the campaign wizard
[[feedotter.secondary_color]]The color(hex) selected as secondary color in the campaign wizard
[[feedotter.button_color]]The color for buttons and calls to action links
[[feedotter.headline]]Big, bold headline text used in select templates
[[feedotter.subheader]]A subheadline used in select templates
[[feedotter.header_image_url]]Certain templates support the upload of a header banner image
[[feedotter.company_logo_url]]The url of the logo you uploaded during the campaign wizard process
[[feedotter.post_title_char_limit]]Certain templates support the changing of the max title length via the UI
[[feedotter.post_body_char_limit]]Certain templates support the changing of the max body length via the UI
[[feedotter.personalize_html]]Works with curated emails only. Allows user to add a personal block of html text and a greeting to each newsletter
[[feedotter.personalize_greeting]]Works with curated emails only. Allows user to add a personal block of html text and a greeting to each newsletter
Company values typically used for a footer. As provided in the Footer Settings UI area.
Social profile urls as provided in the Footer Settings UI area.
[[feedotter.unsubscribe_link]]Displays the proper unsubscribe link based on your sending software
[[feedotter.view_as_webpage_link]]Displays a link to view the email as a webpage based on your sending software.

Custom Tokens

You can also define custom field tokens in your HTML.  Custom tokens allow you to make certain parts of your email editable from the FeedOtter UI.  This is great for personalizing greetings, swapping out headlines, adding ad content or various other CTAs.  The idea is that you can easily change basic elements without the risk of breaking the email code.

In the example below we define 3 custom fields in a special <script> JSON block added to the bottom of our email's <head> section.  Currently, we support 3 types of custom fields; text, html, image.  
    <script type="application/ld+json" id="custom">
      {"prettyName": "Sample HTML","name": "samplehtml","type": "html","default": "<p>a block of html</p>"},
      {"prettyName": "Headline","name": "headline","type": "text","default": "Some plain text"},
      {"prettyName": "Ad Image","name": "adimage1","type": "image","default": "https://via.placeholder.com/350x250"}
    <h1>  [[custom.headline]]</h1>
    <p><img src="[[custom.adimage1]]"></p>
Each custom field will then appear in the FeedOtter UI when editing an email. You can edit text, upload images, or tweak basic html text to customize emails.
FeedOtter Custom Fields Appearing in the UI
Custom fields are also available for use when using the Send Now feature.
Custom fields are available for use with Send Now
Custom fields can be used in many creative ways.  You can even bind the default value of a custom field to data from your RSS feeds!

Looping Through RSS Feeds and Displaying Content

Here we cover the basic elements of a FeedOtter data-driven RSS email.

The Post Loop

The post loop is the most important component of any FeedOtter email design. The code shown here will loop through your RSS feed and display each the title, url, and description(with html stripped) for each post in your RSS feed.

    //A very basic post loop example
    [% for post in feedotter.posts %]    
    [% endfor %]
Slicing the Post Loop

In many cases you may want to display a specific post or posts from an RSS feed.  We do this by applying a "slice" filter to the feedotter.posts element.

Example 1. Displays only the first post in the feed. 
"loop through the feed, starting at post 0, and stop after 1 post"

Example 2. Displays posts 2-5 in the feed.
"loop through the feed, starting at post 1, and stop after 4 posts"

Pay special attention to the | slice(0, 1) part of the loop definition. The first number in the slice() function is the starting point so 0=first post in a feed. The second number is the length or number of posts to display or loop through.

    //Example 1.
    [% for post in feedotter.posts | slice(0,1) %]
    	### Displaying Post 1 Only ###
    [% endfor %]
    //Example 2.
    [% for post in feedotter.posts | slice(1,4) %]
    	### Displaying Posts 2-5 ###
    [% endfor %]
Looping through Multiple Feeds

FeedOtter's advanced plans support combining multiple feeds into a single feed or displaying feeds in separate loops. This feature can help you consolidate data from multiple places and display content in different sections of a newsletter with ease.

Example 1.
There are two loops. The first loop displays the first post from RSS Feed 1. The second loop displays 3 posts from RSS Feed 2. The important part to note is the loop text "feedotter.posts".  Adding a number to this will allow you to access the data from multiple feeds. "feedotter.posts" is always feed1 -the topmost feed shown in the UI.

Example 2.
In this example we use a special filter to combine the data from feeds 1 and 2. This filter will remove duplicates and order all posts by their published date.

     //Example 1.
     ###Display 1 post from RSS Feed 1###
     [% for post in feedotter.posts | slice(0,1) %]
          [[post.post_title]] - [[post.post_url]]
     [% endfor %]

     ###Display 3 posts from RSS Feed 2###
     [% for post in feedotter.posts2 | slice(0,3) %]
          [[post.post_title]] - [[post.post_url]]
     [% endfor %]
     //Example 2.
     ###Combined Posts From All Feeds. De-duped and sorted by Published Date###
     [% for post in feedMerge([feedotter.posts, feedotter.posts2]) %]
          [[post.post_date | date("n/j/Y")]] == [[post.post_title]]
     [% endfor %]

Formatting Filters

//Truncate to 200 characters of text(200), preserve words(true), add ellipses("...")
[[post.post_excerpt_text | truncate(200,true,"...")]]

//Truncate to 450 characters of text but preserve sentences
[[post.post_excerpt_text | truncate_sentence(450)]]
Date Formatting
In general FeedOtter can use any date formatting supported by PHP as seen here: http://php.net/manual/en/datetime.formats.date.php
[[feedotter.send_date | date("F d")]] //the date FeedOtter sent your email formatted as: October 25

FeedOtter uses the TWIG template language.  As such ANY of the TWIG supported filters and formatters are available to use to manipulate data and display variations.  Here we will give examples of the some commonly used formatters.

Helpful Marketing Automation-Related Merge Codes

FeedOtter supports the usage of your email platform’s merge codes as well.  This is useful to insert personalization (first name etc…) or other data fields from your email platform.  Here are several common and useful examples.


{{system.viewAsWebpageLink:default=edit me}}
{{lead.First Name:default=edit me}}

Full list of Marketo merge tokens



Full list of Pardot Classic Variables

PARDOT 2020+:


Full list of Pardot HML Variables


Subject Line Merge Codes

Certain merge codes are available for use in your subject line they are listed below.

Best Practice: Subject lines should not exceed 100 characters so we always recommend using a truncated post title.

//Insert the title of the most recent post in the subject line
[[feedotter.latest_post_title|truncate(40,true,"...")]] //truncated example

//Date examples
[[feedotter.send_date | date("F d")]] //formatted October, 25

Social Share Icons / Links

While some FeedOtter templates come with built in social sharing icons. You may want to add your own. You can do this by adding the below code into the feedotter.post loop.
<a target="_blank" href="https://twitter.com/intent/tweet?text=[[post.post_title]]&url=[[post.post_url]]" style="border:none !important;margin-right:5px;">
	<img src="https://storage.googleapis.com/feedotter-com.appspot.com/social_icons/color_circle_1/twitter.png" title="Twitter" alt="Twitter" width="20" border="0" />

<a target="_blank"  href="https://www.linkedin.com/shareArticle?mini=true&url=[[post.post_url]]" style="border:none !important;margin-right:5px;">
<img src="https://storage.googleapis.com/feedotter-com.appspot.com/social_icons/color_circle_1/linkedin.png"  title="LinkedIn" alt="LinkedIn" width="20" border="0"  />

<a target="_blank"  href="https://www.facebook.com/sharer/sharer.php?u=[[post.post_url]]" style="border:none !important;margin-right:10px;">
<img src="https://storage.googleapis.com/feedotter-com.appspot.com/social_icons/color_circle_1/facebook.png"  title="Facebook" alt="Facebook" width="20" border="0" />

Here’s an example of how we implemented social sharing icons on our Almeria template.

Conditional IF/ELSE, Ternary statements

Often it is desirable to show/hide content based on whether Tag values are present.  This can be done using conditional tags.  Here are some examples:

//Basic IF Statement
[% if post.image_url == true %]
<img src="[[post.image_url]]">
[% endif %]

[% if post.image_url %]
<img src="[[post.image_url]]">
[% else %]
<img src="http://placehold.it/600x400">
[% endif %]

//Ternary IF / ELSE
[[post.image_url ? post.image_url : 'http://placehold.it/600x400']]

Non-RSS XML Values

While FeedOtter requires a valid RSS feed to supply data.  We can also read additional, custom xml values.  Client’s have used this to supply custom images and descriptions along with the standard RSS data fields.
This can be especially useful when building data-driven emails from job boards, news sites, and eCommerce applications.
Below is a partial RSS entry.  Note the node:

<title>Beautiful Painting of saharanpur</title>
<price cost="$179,000" age="2,000 years" condition="perfect"></price>

Here is how to access the custom_image property in the FeedOtter post loop:

[% for post in feedotter.posts %] //standard post loop

//the post.asArray provides direct access to any xml fields in the <item> node of the RSS feed

[% endfor %]

You can also access attributes of custom elements such as the cost=”$179,000″.  The post.asArray.price.attr contains all of the attributes on that node.

[% for post in feedotter.posts %] //standard post loop

//the post.asArray provides direct access to any xml fields in the <item> node of the RSS feed
[[post.asArray.price.attr.cost]]  // displays $179,000
[[post.AsArray.price.attr.age]] // 2,000 years
[[post.asArray.price.attr.condition]] // perfect

[% endfor %]

Working with Multiple RSS Feeds

Applies to: Automated Emails

One of FeedOtter's most powerful features is the ability to incorporate multiple RSS feeds into a single email. Customers have used this features to automate complex multi-section emails, displaying categories of content, or content from multiple blogs or news sites in a single email.

While using multiple feeds is a more advanced use-case and requires a Plus plan or higher it can be a great way to automate more elaborate emails.

This first code sample shows how to display content from multiple feeds in an html email.  Each additional feed you add to your campaign enables a new loop  feedotter.posts, feedotter.posts2 and so on.

You can loop through content using and use the familiar slice() filter to access specific sections of the feed content.


Display 1 post from RSS Feed 1

[% for post in feedotter.posts | slice(0,1) %]

[[post.post_title]] - [[post.post_url]]

[% endfor %]

Display 3 posts from RSS Feed 2

[% for post in feedotter.posts2 | slice(0,3) %]

[[post.post_title]] - [[post.post_url]]

[% endfor %]
The second example shows how to "braid" or combine multiple RSS feeds into a single FeedOtter loop object.

Combined Posts From All Feeds. De-duped and sorted by Published Date

[% for post in feedMerge([feedotter.posts, feedotter.posts2]) %]

[[post.post_date | date("n/j/Y")]] == [[post.post_title]]

### [% endfor %]
Ready to Save Hours of Email Creation Time?

FeedOtter is more than just email automation.  We allow you to create routine emails in minutes that previously took hours.

schedule a demo