push

Welcome to our newly overhauled Zephyr pages! See our new Overview, Examples, and Index.
Feedback is welcome at bottom of each page.

Description

Pushes a new item to the end of an existing array.

push ( "array_name", "additional item" )

Example

{list_of_numbers = [1,2,3,4]}
{push("list_of_numbers", 5)}  ...... makes list_of_numbers = [1,2,3,4,5]

Note: this can also be accomplished in the following way:

{a = ['hey','hi']}
{a = a + ['hello']} ........ pushes 'hello' into a

Within a foreach loop or a map‘s lambda function, you cannot use push on the loop’s iterated array or map’s array parameter.

For example, the following code would result in an error:

{numbers = [1,2,3]}
{map(numbers, lambda n: push('numbers', n))}

Have a Dynamic Welcome Message Based on Last List Signup

Use Case: Within a Welcome email, you want to display the name of the Natural List a user most recently signed up to. Using push() in conjunction with sort(), you can display the name of the most recent Natural List a user was added to.

Zephyr:

{lists = []}
{foreach profile.lists_signup as k,v}
{push("lists",{"name":k,"time":v})}
{/foreach}
{listName = first(sort(lists,'-time')).name}
Thank you for signing up to our {listName} list!

Output: Thank you for signing up to our Daily Newsletter list!

Explanation: This script loops through the “lists_signup” parameter on each user’s “profile object,” assigning two temporary values: “k” (the key, in this instance, the list name) and “v” (the value, in this instance, the list signup time). We then use the push() function to add those values as “name” and “list” into an array called “lists.” Next, a a local variable called “listName” is created, and for the value, the sort() function orders this array by newest to oldest list signup time (“-time”), and then isolates the first value, i.e. the latest list the user signed up to. The {listName} variable is then displayed in the welcome message in the template.

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.

Display the Intersection of User-Interested and Trending Content

Use Case: Using collaborative filtering, you wish to find all items that are “trending” in your Content Library, but you only want to display the top three of those items to users based on user interest data from your Content Library. Used in conjunction with the personalize() function.

Zephyr:

{**Find 100 items a user is interested in and 100 items that are popular**}
{interestContent = personalize({"algorithm":"interest","size":100})}
{popularContent = personalize({"algorithm":"popular", "size":100})}

{**Desired number of items**}
{recNum = 10}

{**FInd the intersect of the popular and interested items**}
{personalizedContent = content_intersect(interestContent,interestContent)}

{**Create a backup length if there are less than the number of desired item**}
{backupLength = recNum - length(personalizedContent)}

{**If the length of backup items is greater than 0, find unique content in the interestContent object to backfill the remaining items**}

{if backupLength > 0}

{usedcontent = []}
{personalizedContent = filter(personalizedContent, lambda c: (contains(usedcontent, c.url) ? false : push("usedcontent", c.url) || true))}
{backupContent = filter(interestContent, lambda c: (contains(usedcontent, c.url) ? false : push("usedcontent", c.url) || true))}

{backupContent = personalize({
"algorithm" : "interest",
"size": backupLength,
"content" : backupContent
})}

{personalizedContent = personalizedContent + backupContent}

{/if}

{**Run personalization**}
{personalizedContent = personalize({
"algorithm" : "interest",
"size": 10,
"content" : personalizedContent
})}

In the Code:

<p>Here are hot items we think you'll love</p>
{foreach personalizedContent as c}
{c.title}<br/>
{/foreach}

Output:

Here are hot items with think you’ll love

Item 1

Item 2

Item 3

Explanation:

This script uses the personalize() function to recommend content based on two algorithms: Interest (based on on-site browsing) and what’s popular (pieces of content that have the most purchases or the most pageviews). It starts by creating two content objects based on those algorithms: One called “interestContent”, which finds 100 items a user has displayed personal interest in; and one called “popularContent”, which is the 100 globally most popular items. Ultimately, you want an overlap of ten items to show to each user (i.e., ten items that they are interested in that are also most popular), and that recommendation length is set in the “recNum” assignment. Next, in order to find the overlap between the two, the content_intersect() function is used to find how much content exists between “interestContent” and “popularContent”, which creates a new content object called “personalizedContent”. Next, there’s a check of the length of this object (i.e., exactly how many items existed in both sections). This number is subtracted from the “recNum” value, which creates the “backupLength”. This means if there are only three matching items between the interested and popular content objects, the backupLength is “7”, meaning the script will now find seven additionally items to recommend.¬†

To check whether or not backup content is necessary, the next part of the script uses an “if” statement to check if the backupLength is greater than 0. If it is, a dedupe script is run, which uses the contains() function to check the title of every item in a data feed against an array called “usedcontent.” If the title of the item exists in the array, the filter() 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 the “personalizedContent” object, and once on the original “interestContent” object. This second filter is used to create a “backupContent” object, which is the content a user is interested in that’s not in the “popularContent” object. The personalize() function is then run on the “backupContent” object baesd on user interest, and the value of the “backupLength” number (i.e. the number of additional items needed to make it to 10) will determine how many additional items to return. “personalizedContent” is then reassigned to be the other “personalizedContent” object plus the “backupContent”. If there were 10 items or more in the original “personalizedContent” object, then no backup content gets added.

Finally, personalize() is run on “personalizedContent” to get the top ten items for each user, which is then looped through using a “foreach” loop and displayed in the template.

Prompt Signup to Non-Subscribed Lists

Use Case: You manage your lists based on user variables and a Smart List (ex. Your ¬†Technology List criteria is: Member of Master List, tech = 1). You’d like a one-click signup in each email for your users to add themselves to other lists based on user interest. You can do this by maintaining an array of your lists.

Zephyr:

In the Setup:

 

{set(“allLists”,[{“tags”:[“books”],”list”:”Books”,”var”:”books”},{“tags”:[“tech”],”list”:”Tech”,”var”:”tech”},{“tags”:[“politics”],”list”:”Politics”,”var”:”politics”},{“tags”:[“science”,”science-fiction”],”list”:”Science”,”var”:”science”},{“tags”:[“entertainment”,”celebrity”],”list”:”Entertainment”,”var”:”entertainment”}])}
{yourLists = []}

{foreach allLists as c}
{if profile.vars[c.var] == 1 || profile.vars[c.var] == “1”}
{push(“yourLists”, c.list)}
{/if}
{/foreach}

{listDelta = filter(allLists, lambda c: !contains(yourLists, c.list))}

In the Code:

<!--Showing only lists users are interested in-->
 {foreach listDelta as c}
 {if horizon_interest(c.tags) >= 2}
 Click here to sign up to <a href="http://example.com?sailthru_vars[{c.var}]=1">{c.list}</a>!<br/>
 {/if}
 {/foreach}

Output:

Click here to sign up to Books!

Click here to sign up to Tech!

Click here to sign up to Politics!

Click here to sign up to Science!

Explanation:

This script uses an array called “allLists”, which each item is an object with applicable interest tags (optional), the list name, and corresponding variable. An empty array called “yourLists” is then created, a foreach loop then iterates through the allLists array and checks the “profile” object. If the user has that corresponding custom field on their profile and it equals “1” in either the string or numerical data type, the list name gets pushed into the yourLists array, using the push() function. For instance, if a user has the “books” custom field equaling “1” on their profile, the “Books” list is added to their array.

Next, a local variable called “listDelta” is created, which users the filter() function to filter through the allLists array, keeping anything that’s not contained in the yourLists array, by using a bang (“!”), which acts as a “not statement,” in conjunction with the contains() function.

The listDelta array is then looped through in the Code. Using the horizon_interest function, the value of each tag is evaluated on a user-by-user basis. lf their interest score in that tag is greater than “2”, they will be prompted to sign up for that particular list, with the variable name automatically populating as the value of the “sailthru_vars” query parameter, which sets a custom field on a user upon click. When the user clicks, the variable us placed on their profile with the value of “1”, i.e. “science = 1″.

Top