filter_content

Description

Apply a lambda function to filter out content that meets specified criteria yet is not pinned to a location in a data feed.

list filter_content( array input , lambda definition )

Evaluates a lambda for every element in the list, and returns a new list with only the elements that evaluated to true as well as any items that were saved as a pinned item in Recommendation Manager. This is especially useful for filtering out content items based on their properties, such as URL or tags, or filtering out duplicate content items.

If you want to filter objects other than a data feed, such as arrays, use filter() instead of filter_content(). You should also use filter() if you want to filter data feed content without regard to whether items are pinned.

Examples

Filtering only for pieces of content that are tagged furniture:

{content = filter_content(content, lambda x: contains(x.tags, 'furniture'))}

Filter out pieces of content that are tagged “explicit-content”:

{content = filter_content(content, lambda x: !contains(x.tags, 'explicit-content'))}

Removing duplicate content based on title:

{duplicates = []}
{content = filter_content(content, lambda x: contains(duplicates, x.title)?false:duplicates = duplicates + [x.title] || true)}

Set a Limit on the Number of Items Shown from a Certain Category

Use Case:

You want to ensure that users aren’t shown content based on the same “author” too many times. Instead, you want to limit it to two items max.

Zephyr:

In the Setup:

{max_per_author = 2}
{display_count = 3}

{* Sorts entire content array in interest order, ensuring that most relevant items will be kept for each user *}
{content = personalize({"algorithm": "interest", "content": content, "size": length(content)})}

{* Filter removes any items in excess of max_per_category *}
{author_counts = {}}
{content = filter_content(content, lambda c: ((contains(keys(author_counts), c.author) && author_counts[c.author] >= max_per_author) ? false : ((contains(keys(author_counts), c.author) ? (author_counts[c.author] = author_counts[c.author] + 1) : (author_counts[c.author] = 1)) || true)))}

{* Slice desired number of items for display. Content already sorted in interest order. *}
{content = slice(content, 0, display_count)}

In the Code:

Picked for You!
{foreach content as c}
<a href={c.url}>{c.title}</a> by {c.author}!
<br/>
{/foreach}

Output:

Picked for You!

Alexander Harris elected to Los Angeles House of Representatives by Willow Rosenberg
Get Your First Look at the New iPhone at the Times Square Apple Store by Willow Rosenberg
Spider-Man: Threat or Menace? by J. Jonah Jameson

Show/Hide Code Explanation

This script starts by setting two local variables: a “max_per_author” variable and a “display_count” variable, which are easily editable on a send-by-send basis. In this instance, the “max_per_author” value is set to 2, and the “display_count” is set to 3. It then uses the personalize() algorithm to find all the content the user is interested in. The length() function takes a count of every piece of content in the feed to tell the personalize() function how many items to personalize. By doing the entire length, the content feed is completely reogranized for each user.

Next, an empty object is created, called “author_counts.” In order to fill the object with data, the filter_content() function filters through the content object, using the keys() function in conjunction with the contains() function to check if any “key” (i.e. an author name) is contained within the author_counts object and if the author_count for that particular key is greater than or equal to the author count. Using the Media feed as an example, it’d check if “Willow Rosenberg” is in the object, and if so, if that value is in there more than twice. If so, the script won’t take any further action, but if not, perform another check: If the author_count object already contains that author, then set the value of that author to add “1” to the current value. For instance, if “Willow Rosenberg” were in there once already, the key/value pairing would be “Willow Rosenberg (key) = 1 (value).” Otherwise, if the author_object did not currently contain an instance of that author, the author name is set as the key, with “1” being set as the value. For instance, “Willow Rosenberg = 1″. Since this script iterates through each piece of content, once it gets to “Willow Rosenberg” again as an author, the key/value pair is updated to “Willow Rosenberg = 2″. If it finds that author a third time, it’s removed from the content object for that user.

The content array is then sliced to pull the top items for each user, using the slice() function. The slice starts at position 0 (i.e. the first item in the array) and ends at the value set in the “display_count” variable (in this instance, 3, meaning that content will be the top three items for each user. Finally, a foreach loops iterates through this content array, displaying the title, URL, and author name for each user’s top three pieces of content.

Show Feed Items that Match Terms in Custom Interest Array (With Fallback Content)

Use Case: You have an array of authors a user is following, and on a data feed, you want to match this user variable against a “sailthru.author” content variable in order to create a personalized bucket of content for users. You also want fallback content if there’s no applicable content to show the user.

Zephyr/Code:

Show/hide sample e-commerce feed used for this example
{
"feed": {
	"name": "Ecommerce Feed",
		"url": "http://feed.sailthru.com/ws/feed?id=ecomm"
},
	"content": [
		{
		"title": "To Kill a Mockingbird",
		"description":"The unforgettable novel of a childhood in a sleepy Southern town and the crisis of conscience that rocked it.",
		"date": 1489437759,
		"image": "http://example.com/fiction/tokillamockingbird-full.jpg",
		"weight": 75,
		"tags": [
			"site-store",
			"genre-mystery-thriller",
			"author-harper-lee",
			"classics",
			"fiction",
			"price-11-20"
				],
		"author": "Harper Lee",
		"price": 1500,
		"inventory": 200,
		"vars": {
			"sailthru_genre":"mysteries-and-thrillers",
			"sailthru_category":"books",
			"membership_price":"12.99"
			},
		"url": "http://example.com/fiction/tokillamockingbird/?utm_medium=site",
		"images": {
			"full": {
				"url": "http://example.com/fiction/tokillamockingbird-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/fiction/tokillamockingbird-thumb.jpg"
					}
				}
	},
	{
		"title": "Salem's Lot",
		"description":"Ben Mears has returned to Jerusalem's Lot -- but things are more sinister than he remembers.",
		"date": 1474547794,
		"image": "http://example.com/books/fiction/salemslot-full.jpg",
		"weight": 30,
		"tags": [
			"site-store",
			"genre-horror",
			"author-stephen-king",
			"vampires",
			"fiction",
			"price-5-10"
				],
		"author": "Stephen King",
		"price": 999,
		"inventory": 1567,
		"vars": {
			"sailthru_genre":"horror-and-suspense",
			"sailthru_category":"books",
			"membership_price":"8.15"
			},
		"url": "http://example.com/fiction/salemslot/",
		"images": {
			"full": {
				"url": "http://example.com/books/fiction/salemslot-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/books//fiction/salemslot-thumb.jpg"
					}
				}
	},
	{
		"title": "Women's Leather Jacket",
		"description":"A classic look that never goes out of style with an exposed metal closure that zips at the cuff.",
		"date": 1474547794,
		"image": "http://example.com/fashion/womens/outerwear/leatherjacket-full.jpg",
		"weight": 55,
			"tags": [
			"site-store",
			"womens-clothing",
			"outerwear",
			"material-leather",
			"color-brown",
			"price-201-300"
				],
		"price": 45000,
		"inventory": 1720,
		"vars": {
			"sailthru_color": "brown",
			"sailthru_material":"leather",
			"membership_price":"325.75"
				},
		"url": "http://example.com/fashion/womens/outerwear/leatherjacket/",
		"images": {
			"full": {
				"url": "http://example.com/fashion/womens/outerwear/leatherjacket-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/fashion/womens/outerwear/leatherjacket-thumb.jpg"
					}
				}
	},
	{
		"title": "Invisible Monsters: A Novel",
		"description":"Love, betrayal, petty larceny, and high fashion fuel this deliciously comic novel from the author of Fight Club.",
		"date": 1474547794,
		"image": "http://example.com/books/fiction/invisiblemonsters-full.jpg",
		"weight": 30,
		"tags": [
			"site-store",
			"genre-mystery-thriller",
			"author-chuck-palahniuk",
			"post-modern",
			"fiction",
			"price-5-10"
				],
		"author": "Chuck Palahniuk",
		"price": 899,
		"inventory": 678,
		"vars": {
			"sailthru_genre":"mysteries-and-thrillers",
			"sailthru_category":"books"
			},
		"url": "http://example.com/fiction/invisiblemonsters/",
		"images": {
			"full": {
				"url": "http://example.com/books/fiction/invisiblemonsters-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/books//fiction/invisiblemonsters-thumb.jpg"
					}
				}
	},
	{
		"title": "Men's Chelsea Boots",
		"description": "Look great with jeans or a suit with these slick, black boots.",
		"date": 1474547794,
		"image": "http://example.com/fashion/mens/shoes/chelsea-boots-full.jpg",
		"weight": 40,
			"tags": [
			"site-store",
			"mens-clothing",
			"shoes",
			"material-suede",
			"color-black",
			"price-101-150"
				],
		"price": 14000,
		"inventory": 15,
		"vars": {
			"sailthru_color": "suede",
			"sailthru_material":"leather",
			"membership_price":"115.50"
				},
		"url": "http://example.com/fashion/mens/shoes/chelsea-boots/",
		"images": {
			"full": {
				"url": "http://example.com/fashion/mens/shoes/chelsea-boots-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/fashion/mens/shoes/chelsea-boots-thumb.jpg"
					}
				}
	},
	{
		"title": "From the Fashion Blog: The Most Comfortable Socks You'll Ever Own",
		"description":"They'll literally change your life. Find out where and how to get them!",
		"date": 1489092159,
		"expire_date": 1520628159,
		"image": "http://example.com/fashion/most-comfortable-socks-full.jpg",
		"weight": 25,
		"tags": [
			"site-store",
			"vertical-fashion",
			"type-footwear",
			"author-richard-wilkins",
			"socks",
			"unisex-clothing"
			],
		"author": "Richard Wilkins",
		"vars": {
			"sailthru_category": "fashion",
			"sailthru_storyid": 87422
				},
		"url": "http://example.com/fashion/most-comfortable-socks/",
		"images": {
			"full": {
				"url": "http://example.com/fashion/most-comfortable-socks-full.jpg"
					},
			"thumb": {
				"url": "http://example.com/fashion/most-comfortable-socks-thumb.jpg"
					}
				}
	}
	]
}

On the User Profile:

zephyr example following array stephen king et al

In the Setup:

{*Creating an assignment called your_authors, which is anyone who matches the value of the author var in the content*}
{yourAuthors = filter_content(content, lambda c: contains(profile.vars.following, c.author))}
{*Personalize the order in which authors appear based on interest tags*}
{if length(yourAuthors) > 0}
{yourAuthors = personalize({
 "content" : yourAuthors,
 "algorithm" : "interest",
 "size" : length(yourAuthors)
})}
{else}
{content = personalize({
 "content" : content,
 "algorithm" : "interest",
 "size" : 5
})}
{/if}

In the Code:

<!--Showing new stories if the 'your_authors' array is greater than zero-->
 {if length(yourAuthors) > 0}
 <p>Top books from your favorite authors!</p>
 {foreach yourAuthors as c}
 <p><a href={c.url}>{c.title}</a> by {c.author}</p>
 {/foreach} 
<!--Checking if the user has the following var but with at least one author-->
 {else if(contains(profile.vars,following)) && length(profile.vars.following) > 0}<p>Nothing new from who you're following
 <a href="http://example.com/preferences/">Click here to follow more!</a></p>
But here are some we think you'd like:
{content = personalize({
 "content" : content,
 "algorithm" : "interest",
 "size" : 5
})}
 {foreach content as c}
 <p><a href={c.url}>{c.title}</a> by {c.author}</p>
 {/foreach}
<!--Remaining users who aren't following anyone-->
 {else}
{content = personalize({
 "content" : content,
 "algorithm" : "interest",
 "size" : 5
})}
 <p>You're not following anyone! <a href="http://example.com/preferences/">Click here to start!</a></p>
And here are some we think you'd like to get you started:
 {foreach content as c}
 <p><a href={c.url}>{c.title}</a> by {c.author}</p>
 {/foreach}
 {/if}

Output:

Top books from your favorite authors!

Salem’s Lot by Stephen King
Invisible Monsters by Chuck Palahniuk

Show/Hide Code Explanation

This script uses the filter_content() function in conjunction with the contains() function to find the overlap of the values of a profile variable called “following” (representing authors a user is “subscribed” to), checking for overlap in the content array for any “author” value on each item. Any overlapped items gets added to the “yourAuthors” array. For instance, the example user profile is following Stephen King, Chuck Palahniuk, and Kurt Vonnegut. The first two appear as values for the “author” parameter on two items in the Media feed and are thus added to this user’s “yourAuthor” array.

Next, a check is done on the yourAuthors array to see if it’s greater than 0  (i.e., the user has authors that they’re following who are in the feed). If so, the yourAuthors array is rearranged by the personalize() function to be in order of most interested item to least interested item. Using the length() function on the yourAuthors array tells the personalize() script how many times it should run (in this instance, twice, as there are only two items in the yourAuthors array, meaning length(yourAuthors) = 2). If the user does not have any items in this array, then the personalize() script is run to find 5 items for the entire feed.

In the Code of the template, an “if” statement checks if the length of “yourAuthors” is greater than 0, If it is, loop through each author and show the appropriate content. The next statement uses an “else if” and a contains() function to see if the user has the following var on their profile (by checking all of their profile vars and seeing if following is “contained” in there). If that evaluates to true and the length of the profile user variable is greater than 0 (i.e. there’s at least one author that the user is following), then we can logically determine that the user is following an author, but that author isn’t in the feed. As a result, the content displayed returns 5 items based on user interest data while displaying a message that there isn’t anything new from authors they are following and to start following more.

The last bucket of users are ones who aren’t following any others at all. For these users, the content displayed returns 5 items based on user interest data while displaying a message encouraging them to start following authors for more personalized recommendations.

Display Content with Vars Matching Users’ Interest/Subscription Variables

Use Case: You have individual categories users can follow, each denoted by their own custom field, and on a data feed, you want to match this user field against a “sailthru.category” content variable in order to create a personalized bucket of content for users. You also want a backup section in case someone isn’t following a certain category.

Zephyr:

On the User Profile:

zephyr example tech media news number 1

In the Setup:

{*Creating an assignment called userContent, which will go through each "category" content var, find if you have that same user var with the value of 1, and add it to a "userContent" array*}{userContent = filter_content(content, lambda c: profile.vars[c.vars.sailthru_category] == 1)}{*Personalize the order in which industries appear based on interest tags, pulling the top 3*}{personalizedContent = personalize({
   "content" : userContent,
   "algorithm" : "interest",
   "size" : 3
})}

In the Code:

{if length(userContent) > 0}
<p>Based on your preferences, here are stories you'll enjoy:</p>
{foreach personalizedContent as c}
  <p>From the {c.vars.sailthru_category} category: <a href={c.url}>{c.title}</a></p>
  {/foreach}
{else}
Want personalized recommendations? Tell us what you like <a href="http://example.com/preferences">here</a> to start following a certain category!</p>
{/if}

Output:

(Based on the above user profile)

Here are stories from your selected categories:

From the news category: Spider-Man: Threat or Menace?
From the tech category: Get Your First Look at the New iPhone at the Times Square Apple Store
From the news category: Alexander Harris elected to Los Angeles House of Representatives

(If nothing matches)

Want personalized recommendations? Tell us what you like here to start following a certain category!

Explanation:

This script uses the filter_content() function to iterate through each user profile variable to see if each user has a variable on their profile that matches the value of a content variable on a data feed. For instance, in the Media feed, the values for each sailthru.category custom variable are: media, tech, news, news, and fashion. On the example user profile, the user has “tech”, “media”, and “news” are custom fields that equal “1” (i.e. they are “subscribed” to those categories). Within the filter_content() script, the value of the profile.var (aka custom field) dynamically populates as it iterates through each item in the feed. For instance, for the first item in the Media feed (“Stephen Kings’s New Book…”), the sailthru.category value is “media”. The script check each user profile to see if “profile.vars.media == 1″. If it does, that piece of content is added to a “userContent” variable, which is an array of items from the feed. If not, the item is skipped. For this particular user, since they’re following each category represented in the feed besides “fashion”, only the last article is skipped.

Next, a local variable called “personalizedContent” is created, which uses the personalize() function to pick the top three stories from the “userContent” object based on individual user interest. Finally, in the Code, an “if” statement checks if there’s more than 0 pieces of content in that userContent object (i.e. there’s an item in the feed that matches a category a user is subscribed to). If so, display the category, title, and URL. If not, show a prompt encouraging users to update their preferences and choose categories to follow.

Deduplicate Merged Feed Based on Title

Use Case:

You have two separate data feeds that are in one merged feed. As the dedupe() function doesn’t work between two feeds, you need to dedupe using the filter_content() and contains() functions.

Show/hide sample merged feed used for this example
{ "media": { "feed": { "name": "Media Feed", "url": "http://feed.sailthru.com/ws/feed?id=media" }, "content": [ { "title": "Stephen King's New Book is a Real Scream!", "description":"Staff reviewer William Pratt gives his review of the thrilling new Stephen King novel and tells you whether it's a buy or a miss.", "date": 1489437759, "expire_date": 1520973759, "image": "https://example.com/media/stephen-king-new-book-full.jpg", "weight":10, "tags": [ "site-blog", "vertical-media", "type-books", "author-william-pratt", "format-article", "stephen-king", "horror-fiction" ], "author": "William Pratt", "vars": { "sailthru_category": "media", "sailthru_storyid": 12345 }, "url": "http://example.com/media/stephen-king-new-book/?utm_source=web", "images": { "full": { "url": "https://example.com/media/stephen-king-new-book-full.jpg" }, "thumb": { "url": "https://example.com/media/stephen-king-new-book-thumb.jpg" } } }, { "title": "Get Your First Look at the New iPhone at the Times Square Apple Store", "description":"Find out how you can get a sneak peak of Apple's newest tech...", "date": 1489351359, "expire_date": 1520887359, "image": "https://example.com/tech/new-iphone-times-square-full.jpg", "weight":5, "tags": [ "site-blog", "vertical-tech", "type-smartphones", "author-willow-rosenberg", "format-video", "apple", "iphone", "region-new-york-city" ], "author": "Willow Rosenberg", "vars": { "sailthru_category": "tech", "sailthru_storyid": 78945 }, "url": "http://example.com/tech/new-iphone-times-square/", "location": [ 40.7589, -73.9851 ], "images": { "full": { "url": "https://example.com/tech/new-iphone-times-square-full.jpg" }, "thumb": { "url": "https://example.com/tech/new-iphone-times-square-thumb.jpg" } } }, { "title": "Alexander Harris elected to Los Angeles House of Representatives", "description":"Read more to find out his five-point plan for his county and more", "date": 1489264959, "expire_date": 1520800959, "image": "https://example.com/tech/new-iphone-times-square-full.jpg", "weight":3, "tags": [ "site-blog", "vertical-news", "type-usa", "author-willow-rosenberg", "region-los-angeles", "house-of-representatives", "alexander-harris" ], "author": "Willow Rosenberg", "vars": { "sailthru_category": "news", "sailthru_storyid": 41612 }, "url": "http://example.com/news/alexander-harris-elected/", "location": [ 34.0522, -118.2437 ], "images": { "full": { "url": "http://example.com/news/alexander-harris-elected-full.jpg" }, "thumb": { "url": "http://example.com/news/alexander-harris-elected-thumb.jpg" } } }, { "title": "Spider-Man: Threat or Menace?", "description":"Who is this masked man, and what does he really want?", "date": 1489178559, "expire_date": 1520714559, "image": "", "weight": 40, "tags": [ "site-blog", "vertical-news", "author-j-jonah-jameson", "spider-man", "vigilantism", ], "author": "J. Jonah Jameson", "vars": { "sailthru_category": "news", "sailthru_storyid": 81263 }, "url": "http://example.com/news/spider-man-threat-or-menance/", "location": [ 40.7589, -73.9851 ], "images": { "full": { "url": "" }, "thumb": { "url": "" } } }, { "title": "From the Fashion Blog: The Most Comfortable Socks You'll Ever Own", "description":"They'll literally change your life. Find out where and how to get them!", "date": 1489092159, "expire_date": 1520628159, "image": "http://example.com/fashion/most-comfortable-socks-full.jpg", "weight": 25, "tags": [ "site-blog", "vertical-fashion", "type-footwear", "author-willow-rosenberg-wilkins", "socks", "unisex-clothing" ], "author": "Willow Rosenberg", "vars": { "sailthru_category": "fashion", "sailthru_storyid": 87422 }, "url": "http://example.com/fashion/most-comfortable-socks/", "images": { "full": { "url": "http://example.com/fashion/most-comfortable-socks-full.jpg" }, "thumb": { "url": "http://example.com/fashion/most-comfortable-socks-thumb.jpg" } } } ] }, "ecomm": { "feed": { "name": "Ecommerce Feed", "url": "http://feed.sailthru.com/ws/feed?id=ecomm" }, "content": [ { "title": "To Kill a Mockingbird", "description":"The unforgettable novel of a childhood in a sleepy Southern town and the crisis of conscience that rocked it.", "date": 1489437759, "image": "http://example.com/fiction/tokillamockingbird-full.jpg", "weight": 75, "tags": [ "site-store", "genre-mystery-thriller", "author-harper-lee", "classics", "fiction", "price-11-20" ], "author": "Harper Lee", "price": 1500, "inventory": 200, "vars": { "sailthru_genre":"mysteries-and-thrillers", "sailthru_category":"books", "membership_price":"12.99" }, "url": "http://example.com/fiction/tokillamockingbird/?utm_medium=site", "images": { "full": { "url": "http://example.com/fiction/tokillamockingbird-full.jpg" }, "thumb": { "url": "http://example.com/fiction/tokillamockingbird-thumb.jpg" } } }, { "title": "Salem's Lot", "description":"Ben Mears has returned to Jerusalem's Lot -- but things are more sinister than he remembers.", "date": 1474547794, "image": "http://example.com/books/fiction/salemslot-full.jpg", "weight": 30, "tags": [ "site-store", "genre-horror", "author-stephen-king", "vampires", "fiction", "price-5-10" ], "author": "Stephen King", "price": 999, "inventory": 1567, "vars": { "sailthru_genre":"horror-and-suspense", "sailthru_category":"books", "membership_price":"8.15" }, "url": "http://example.com/fiction/salemslot/", "images": { "full": { "url": "http://example.com/books/fiction/salemslot-full.jpg" }, "thumb": { "url": "http://example.com/books//fiction/salemslot-thumb.jpg" } } }, { "title": "Women's Leather Jacket", "description":"A classic look that never goes out of style with an exposed metal closure that zips at the cuff.", "date": 1474547794, "image": "http://example.com/fashion/womens/outerwear/leatherjacket-full.jpg", "weight": 55, "tags": [ "site-store", "womens-clothing", "outerwear", "material-leather", "color-brown", "price-201-300" ], "price": 45000, "inventory": 1720, "vars": { "sailthru_color": "brown", "sailthru_material":"leather", "membership_price":"325.75" }, "url": "http://example.com/fashion/womens/outerwear/leatherjacket/", "images": { "full": { "url": "http://example.com/fashion/womens/outerwear/leatherjacket-full.jpg" }, "thumb": { "url": "http://example.com/fashion/womens/outerwear/leatherjacket-thumb.jpg" } } }, { "title": "Invisible Monsters: A Novel", "description":"Love, betrayal, petty larceny, and high fashion fuel this deliciously comic novel from the author of Fight Club.", "date": 1474547794, "image": "http://example.com/books/fiction/invisiblemonsters-full.jpg", "weight": 30, "tags": [ "site-store", "genre-mystery-thriller", "author-chuck-palahniuk", "post-modern", "fiction", "price-5-10" ], "author": "Chuck Palahniuk", "price": 899, "inventory": 678, "vars": { "sailthru_genre":"mysteries-and-thrillers", "sailthru_category":"books" }, "url": "http://example.com/fiction/invisiblemonsters/", "images": { "full": { "url": "http://example.com/books/fiction/invisiblemonsters-full.jpg" }, "thumb": { "url": "http://example.com/books//fiction/invisiblemonsters-thumb.jpg" } } }, { "title": "Men's Chelsea Boots", "description": "Look great with jeans or a suit with these slick, black boots.", "date": 1474547794, "image": "http://example.com/fashion/mens/shoes/chelsea-boots-full.jpg", "weight": 40, "tags": [ "site-store", "mens-clothing", "shoes", "material-suede", "color-black", "price-101-150" ], "price": 14000, "inventory": 15, "vars": { "sailthru_color": "suede", "sailthru_material":"leather", "membership_price":"115.50" }, "url": "http://example.com/fashion/mens/shoes/chelsea-boots/", "images": { "full": { "url": "http://example.com/fashion/mens/shoes/chelsea-boots-full.jpg" }, "thumb": { "url": "http://example.com/fashion/mens/shoes/chelsea-boots-thumb.jpg" } } }, { "title": "From the Fashion Blog: The Most Comfortable Socks You'll Ever Own", "description":"They'll literally change your life. Find out where and how to get them!", "date": 1489092159, "expire_date": 1520628159, "image": "http://example.com/fashion/most-comfortable-socks-full.jpg", "weight": 25, "tags": [ "site-store", "vertical-fashion", "type-footwear", "author-richard-wilkins", "socks", "unisex-clothing" ], "author": "Richard Wilkins", "vars": { "sailthru_category": "fashion", "sailthru_storyid": 87422 }, "url": "http://example.com/fashion/most-comfortable-socks/", "images": { "full": { "url": "http://example.com/fashion/most-comfortable-socks-full.jpg" }, "thumb": { "url": "http://example.com/fashion/most-comfortable-socks-thumb.jpg" } } } ] } }

Zephyr:

{usedtitle = []}

{mediaContent = filter_content(media.content, lambda c: (contains(usedtitle, c.title) ? false : push("usedtitle", c.title) || true))}
{ecomContent = filter_content(ecomm.content, lambda c: (contains(usedtitle, c.title) ? false : push("usedtitle", c.title) || true))}

<p>From the Blog:</p>
{foreach mediaContent as c}
<a href={c.url}>{c.title}</a>
<br/>

{foreach}
<p>From the Store:</p>
{foreach ecomContent as c}
<a href={c.url}>{c.title}</a>
<br/>
{foreach}

Output:

From the Blog:

From the Fashion Blog: The Most Comfortable Boots You’ll Ever Own
Spider-Man: Threat or Menace?
Alexander Harris elected to Los Angeles House of Representatives
Get Your First Look at the New iPhone at the Times Square Apple Store
Stephen King’s New Book is a Real Scream!

From the Store:
Women’s Leather Jacket
Men’s Chelsea Boots
To Kill a Mockingbird
Salem’s Lot
Invisible Monsters: A Novel

Based on the merged feed example, the “From the Fashion Blog: The Most Comfortable Socks You’ll Ever Own” item, which exists in both feeds, will be excluded from the “ecomContent” object.

Explanation: This script users the contains() function to check the title of every item in a data feed against an array called “usedtitle.” If the title of the item exists in the array, the filter_content() function removes it from the feed (this means that the title already occurred once, and it is a duplicated item). In this example, the filter is performed twice: Once on an external RSS feed, and once on a Sailthru Content Feed.

Filter for Content Between Two Price Points (Based on Sailthru Prediction of User’s Upcoming Average Order Value)

Use Case: Based on Prediction Manager user predictions (in this case, aov_7), we can find how much a user is likely to purchase and then limit item recommendations to only items that are slightly lower or slightly higher than what the user is likely to spend.

Zephyr:

In the Setup:

{aov7 = profile.vars.predictions.aov_7.num}
{content = filter_content(content, lambda c: c.price > (.5 * aov7)  && c.price < (1.5 * aov7))}

In the Code:

Here are some items we think you'd love!
{foreach content as c}
{c.title} for ${number(c.price/100,2)}
<br/>
{/foreach}

Output:

To Kill a Mockingbird for $15.00
Salem's Lot for $9.99
Invisible Monsters: A Novel for $8.99

Explanation: This script sets a local variable called "aov7", which is equal to the numeric predicted user Average Order Value for the next 7 days (aka AOV7 if you're using Prediction Manager). Using the filter_content() function, products from the content feed are filtered out (unless they're pinned) to only include products that are between a certain range, in this case, between 50% of what the user is likely to spend and 150% of what the user is likely to spend, dependent on their personal AOV7.

Top