How to Create Custom Email 
Templates for FeedOtter

A guide to creating custom html email templates using FeedOtter’s template system

Creating A Custom RSS Email Template For FeedOtter

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 emails features.

Part 1. FeedOtter Tokens

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 related 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

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 or 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..

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
[[feedotter.company_name]]
[[feedotter.company_address]]
[[feedotter.company_city]]
[[feedotter.company_state]]
[[feedotter.company_zip]]
[[feedotter.company_country]]
Company values typically used for a footer. As provided in the Footer Settings UI area.
[[feedotter.company_twitter_url]]
[[feedotter.company_facebook_url]]
[[feedotter.company_linkedin_url]]
[[feedotter.company_youtube_url]]
[[feedotter.company_google_plus_url]]
[[feedotter.company_instagram_url]]
[[feedotter.company_pinterest_url]]
[[feedotter.company_blog_url]]
[[feedotter.company_url]]
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.  
  <head>
    <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"}
    ]
	</script>
  </head>
  <body>
    <h1>  [[custom.headline]]</h1>
    <div>[[custom.samplehtml]]</div>
    <p><img src="[[custom.adimage1]]"></p>
  
  </body>
  </html
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!

Part 2. Accessing RSS and Post Data in Your Email

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 %]    
    	[[post.post_title]]
    	[[post.post_url]]
    	[[post.post_description_text]]
    [% 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 ###
    	[[post.post_title]]
    	[[post.post_url]]
    	[[post.post_description_text]]
    [% endfor %]
    
    //Example 2.
    [% for post in feedotter.posts | slice(1,4) %]
    	### Displaying Posts 2-5 ###
    	[[post.post_title]]
    	[[post.post_url]]
    	[[post.post_description_text]]
    [% endfor %]
    
    

Part 3. Formatting

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.

Truncation
//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

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.

MARKETO:

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

Full list of Marketo merge tokens

PARDOT LEGACY:

%%unsubscribe%%
%%email_preference_center%%

Full list of Pardot Classic Variables

PARDOT 2020+:

{{Unsubscribe}}
{{View_Online}}
{{EmailPreferenceCenter}}
{{Recipient.FirstName}}

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]]
[[feedotter.latest_post_title|truncate(40,true,"...")]] //truncated example

//Date examples
[[feedotter.send_date]]
[[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>

<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>

<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" />
</a>

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 / ELSE
[% 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:

<item>
<title>Beautiful Painting of saharanpur</title>
<link>
https://uat.rauantiques.com/catalog/product/view/id/102845/
</link>
...
<custom_image>
<![CDATA[
https://cdn-uat.rauantiques.com/media/catalog/product/cache/1/image/265x/9df78eab33525d08d6e5fb8d27136e95/1/_/1_30-6635_1_3.png
]]>
</custom_image>
<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
[[post.asArray.custom_image.value]] 

[% 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 %]