Use Feeds and Content Data in Templates

Code your template to display content from a data feed--product or article names, plus their page URLs, image URLs, and other metadata.

In addition to coding the template, you will need to:

  • Set up the intended data feed(s) in the platform. Note that some configurations of the personalize function can bring your Content Library items into a template without the need for a feed. That data array will use the same format described on this page.
  • Associate a feed with the template or with a specific campaign or triggered send.

Your feed data will be made available to the template via an array named content. You can use the instructions on this page to access and display that content. Before you do, you can opt to pass that data through the Zephyr function personalize or horizon_select in order to personalize the content choices made for the individual recipient. In addition, a user in Recommendations can customize the sequence of content items that will appear in the feed.

Code a Template Using a Data Feed

Single Feed

When you create a Content Feed with items from your Content Library, the system produces a JSON feed format that is well-suited to being parsed and handled within your emails. If you instead import your own feed, it is converted to JSON (if not already JSON).

This format can be seen by clicking the Preview  icon  in Data Feeds or by clicking the Test button in the Advanced tab of the template/campaign editor.

Example:

Copy
 {"content":[ 
        {"title" : "Article Title #1",    
        "url" : "http://path/to/url",    
        "tags" : ["tag-1", "tag-2", "tag-3"],    
        "description" : "Description of article here",
        "author" : "Jane Smith",
        "vars" : {
        "source" : "AP"},       
        "image" : "http://path/to/image.jpg"},
        {"title" : "Article Title #2",    
        "url" : "http://path/to/url2",
        "tags" : ["tag-5", "tag-6", "tag-7"],   
        "description" : "Description of article here",
        "author" : "Joe Smith",
        "vars" : {
        "source" : "AP"},     
        "image" : "http://path/to/image2.jpg"} 
       ] 
 }

You can force this JSON to render as RSS by adding &format=rss> to the end of a Content Feed URL. This URL is displayed when clicking the eyeball icon next to the feed on the main Data Feeds page.

For example:

Copy
http://cb.sailthru.com/ws/feed?id=abcde123456&format=rss

The system supports two types of images in a data feed:

image.thumb and image.full

Code into Template

The Subject line allows for Zephyr syntax. To match the Subject line to the lead article, you could include:

Copy
{content[0].title}

Examples

Below are some examples of Zephyr syntax to pull specific values from a single feed. If you are not familiar with programming, note that array content is numbered starting with "0", not "1".

Call Article Title #1

Copy
<h2>{content[0].title}</h2>

Call Article Image #1

Remember to set the image height and width attributes.

Copy
<img src="{content[0].image}" />

Call Article Thumb Image from a Personalization Engine Content Feed

Requires the sailthru.image.thumb meta tag

Copy
<img src="{content[0].images.thumb.url}" />

Call Article Full Image from a Personalization Engine Content Feed

Requires the sailthru.image.full meta tag

Copy
<img src="{content[0].images.full.url}" />

Call Article URL #1

Copy
<a href="{content[0].url}">Click here</a>

Call Article Description #1

Copy
<p>{content[0].description}</p>

For-Each Loop

You can also loop through the articles in the template instead of coding up each one by using a {foreach} loop.

Use "content as [a single letter or other short variable name]" for brevity in subsequent references to the content array. For example, "content as c" in the code below.

Copy
   {foreach content as c}
        <a href="{c.url}">{c.title}</a>        <img src="{c.image}">        {c.description}<a href="{c.url}">Read more</a> 
   {/foreach}

To limit the number of items displayed in your template when using a foreach loop, use the slice function. The example below starts at the first item (position 0) and running five times, pulling in the first five stories.

Copy
{foreach slice(content, 0,5) as c}

        <a href="{c.url}">{c.title}</a>        <img src="{c.image}">        {c.description}<a href="{c.url}">Read more</a>{/foreach}

Suppose we want to show five articles in a very simple format. The lead story will contain a full-size photo. The other stories will not and will have smaller headlines.

Copy
<div>    <img src="{content[0].image.full}" width="300" height="200" />    <div style="font-size:24px">      <a href="{content[0].url}">{content[0].title}</a>     {foreach slice(content, 0,5) as c}
       <div>         <a href="{c.url}">{c.title}</a>       <div>     {/foreach}
   <div>  </div>

Merged Feed

For this example, we merged together two feeds, one with the key "Firstfeed" and another with the key"Secondfeed".

Copy
{ "Firstfeed" : {       
    "content" : [
       {
        "title" : "First Feed Article Title #0", 
        "url" : "http://path1/to/url0",
        "description" : "First Feed Article Description #0",
        "content" : "First Feed Content #0"}
      },           
      {
          "title" : "First Feed Article Title #1",               
          "url" : "http://path1/to/url1",               
          "description" : "First Feed Article Description  
           #1",               
          "content" : "First Feed Content #1"       }
    ]   
  },
"Secondfeed" : { 
    "content" : [
       {               
          "title" : "Second Feed Article Title #0",               
          "url" : "http://path2/to/url0",               
          "description" : "Second Feed Article Description 
          #0",               
          "content" : "Second Feed Content #0"       },              
       {
          "title" : "Second Feed Article Title #1",               
          "url" : "http://path2/to/url1",               
          "description" : "Second Feed Article Description 
          #1",               
          "content" : "Second Feed Content #1"           
      }       
    ]   
  } 
}

Code into Template

Here are some examples of Zephyr code to pull specific values from the above feed. If you are not familiar with programming, note that arrays start with "0" and not "1".

First Feed, Article URL #1

Copy
<h2>{Firstfeed.content[0].title}</h2>

Second Feed, Article URL #1

Copy
<a href="{Secondfeed.content[0].url}">click here</a>

Second Feed, Article Description #1

Copy
<p>{Secondfeed.content[0].description}</p>

If you wish to pull in a data feed without importing it, see Data Feeds Overview for more information.

Support for Recommendations

Feed Requirements for Recommendations

Content Feeds are already compatible with Recommendations. If you import your own feed, use the following instructions to ensure that your feed is compatible.

A top-level key name (e.g. content) is required, with its value being an array of content-item objects, each with the following top-level keys:

  • Required
    • url
  • Optional, displayed as primary editable fields
    • image.thumb and image.full (or just image) - URLs of images. Providing thumb and full are recommended as they provide multiple image size options in your template.
    • name> and/or title - Either or both will be displayed as the primary name/title in the feed-editing display.
    • date - The publish date/time in Unix/Epoch format.
    • description
    • tags - An array of strings.
  • Optional - Editable in Custom Fields section
    • Any simple object (string, integer, or boolean)
  • Optional, supported only for viewing its key name in the Custom Fields section
    • Any complex object - The key is displayed in Recommendations but the entire object is retained on the feed and remains accessible to your template code.

For example, all of the data in the content array below would be editable in Recommendations.

Copy
{
    "feed" : {
        "name" : "My Site Feed",
        "url" : "http://feed.sailthru.com/ws/feed?id=46535f7e1ab3121d680e5f53"
    },
    "content" : [
        {
            "title": "Example Product Page Title | My Site",
            "url": "http://www.example.com/myurl”,
            "date": 1458532800,
            "description": "This is my example page",
            "price": 16000,
            "tags": [
                    "examples", "sailthru", 
                    ],
            "images": {
                "full": {
                    "url": "http://www.example.com/images/example-full.jpg"
                }
                "full": {
                    "url": "http://www.example.com/images/example-thumb.jpg"
                }
            }
        },
        {
            <next content object>
        }
    ]
}

Feed Additions Made by Recommendations

When Recommendations is used to "pin" content a position in the feed, the pin location is added as metadata on the content object in the array. Typically, this data is used only by the system, however you may also choose to access this data. A sailthru key is created containing the index of the pinned location, along with other metadata used exclusively by Recommendations. For example, if the user pins the content item to the first position in the feed (i.e. 0), the following addition would be found in the content object:

Copy
"sailthru": {
   "pinned": 0
},

Template Requirements for Recommendations Pinning

Pinning is intended for templates that apply the personalize or horizon_select function to your content array, personalizing the selection of content for each user. Pinning allows a Recommendations user to set custom positions for any given content items for a given time period (e.g. a "featured item" at the top of today's campaign), and have the positions respected by these personalization functions. These functions will personalize all other content slots, but leave pinned items in their place.

After these functions return a content array for the user, if this array is not modified by additional functions, pinned positions will be maintained in your message. However, pinning may be affected if you are using functions that modify the content array in a way that removes pinned content, removes pin metadata on pinned content, or reorders content. Please see the table below for information on these functions, and contact Support if you need assistance.

bucket_list

The pinning information will be transferred to the buckets, so an item pinned in the main feed would jump to that position in the bucket only if Zephyr functions personalize, horizon_select,or filter_content are used on it.

content_intersect

Will not respect pinning, as it can remove pinned content from a feed. The code may be rewritten using Zephyr function filter_content.

filter

Will not respect pinning, as it can remove pinned content from a feed. If you replace every instance of Zephyr function filter with filter_content, your filtering will maintain pinned items.

intersect

Will not respect pinning, as it can remove pinned content from a feed. The code may be rewritten using the Zephyr function filter_content.

map

Transforms elements in your array, so it will affect pinning depending on how you use it.

purchased_items

Will not respect pinning, as it removes or selects only the products a user has purchased. To use pinning in this context, Zephyr function filter_content will need to be used in combination.

slice

When used to isolate certain items in a feed array, slice may drop pinned items. However, slice is often used for display purposes to break up content into sections. In that use case, the function isn't removing content so pinning will be respected.

sort

If used before personalize or horizon_select pinning would be respected, but check for other functions used in conjunction like slice. If sort is used after personalize or horizon_select, expect pinning to be affected.

Data Feed Errors

To avoid sending an empty email due a broken data feed, mass mail sends are automatically canceled and a notification sent if the data feed returns an error.

Errors that prompt the fail-safe send cancel and alert email are HTTP errors, such as 500 or 404. A server that returns an "empty" or "null" feed but with a valid HTTP response will not trigger the failure.

To receive notification of a send cancel, enter your email address in the Report Email field in Campaign Editor  Basics tab.