This section explains how individual data items can be extracted from the data block fetched by the feed. 

Data items can be added on the feed settings page here:

Each data item has a name and a mapping script:

The name will be used later to specify which data goes where in the template.  

The mapping script uses the Liquid templating language. In the simplest case this can be used to extract data.  In more advanced use cases data can be reformatted or logic can be used to make decisions on content based on the data.

Data types and how to reference them

The notation used to pull data from a feed depends on the data type selected, as follows:

Json and XML data is available as a liquid object.  HTML data can be extracted using special filters

Extracting JSON or XML Data

JSON and XML data are both accessed as objects in liquid, so to get a piece of content from a JSON Feed the liquid will look something like:

{{json.something.item.somethingelse[0].thing }}

Whereas for XML the liquid will be of the form:

{{xml.something.item.somethingelse[0].thing }}

It’s easier to write the liquid code if we can see the data structure.  To do this go to the Test tab and open the JSON tree in the Response section.  

Note that XML feeds will also show as a JSON tree.

Click this to open the JSON tree:

Example

This example is from the (publically available) TicketMaster feed and contains details of an event:

Simple Reference

The name of the event is at the top level of the JSON tree:

It can be referenced as json.name: {{json.name}} 

This can then be verified by looking at the test tab:

It’s also worth noting that text can be added before/after the Lliquid that pulls the value in:

Which looks like this in the test tab:

You can also use Liquid filters in value, for example {{ json.name | upcase }} , which outputs this:

Nested Reference

Looking again at the JSON tree, we can see that it starts with a { . Lower down the tree, sales  is lso followed by a { . This means that this is a block of json within the main block. This can be referenced as json.sales .

If we put {{json.sales}} as our data item, we will get the content of that block in JSON format as our value:

{"public":{"startDateTime":"2018-09-14T15:00:00Z","startTBD":false,"endDateTime":"2019-01-01T03:30:00Z"},"presales":[{"startDateTime":"2018-09-12T15:00:00Z","endDateTime":"2018-09-14T03:00:00Z","name":"Live Nation Mobile App Presale","description":"Download the Live Nation iPhone App now to access Live Nation Mobile App Presales. Browse, search, and discover….

In this format, the data in the block isn't too useful. However, we can use the next levels of Liquid to pull out data.

In this example, {{json.sales.public}}  pulls out: {"startDateTime":"2018-09-14T15:00:00Z","startTBD":false,"endDateTime":"2019-01-01T03:30:00Z"} 

We can go deeper than this, like so: {{json.sales.public.startDateTime}}  which will get the start time. We can also apply a filter to display the date and time in a specific format: {{json.sales.public.startDateTime | date: "%a, %b %d %Y" }} . You can read more about the date filter on Shopify's website.

Objects and Arrays

So far we have been looking at blocks which start with ‘{‘,  these are called objects.  They take the form of keys and values.  The key is the name of the piece of data, and it forms a pair with the value.   In this block the keys are ‘name’, and ‘statecode’ and the values are ‘Tennessee’ and ‘TN’:

{
"name": "Tennessee"
"stateCode": "TN"
}

The value can, in turn, be another block.  Consider the following example:

{
"name": "Taxi For Email"
"details": {  
    location: "Location”,  
    email: "hello@taxiforemail.com"  
    }
}

Here the value of ‘details’ is an object, which itself has the keys ‘location’ and email.

Blocks which start with ‘[‘ are not objects; they are arrays. Arrays are not the same as objects.  Here is an example of an array:

[ "item 1", "item 2", "item 3"]

An array is a list of values.  There are no keys.  

For technical reasons, it is quite common to see arrays containing a single block of data in feeds.  So it is common to have to get the first element out of an array:

{ results: [ {   
    "title": "The BFG"  
    }]
}

We can dig in to get the title as follows:

To pull the title from the above array, you can use the code {{json.results.first.title}} . The first keyword is used in Liquid to get the first item in the array. You can also switch this for a number. The equivalent to above is: {{json.results[0].title}} .

With this square bracket notation, any element can be extracted from an array.

In the Ticket Master feed an array of images is given.  The first one is images[0] , the next is images[1]  and so on.  To reference the url of each of the images the following code could be used:

{{json.images[0].url}}
{{json.images[1].url}}

Looping Through Arrays

Liquid supports looping through arrays.  This can be useful for several reasons:

  • In the image array in the TicketMaster feed there are a number of different images, we might want to find the one closest to a particular width to fit nicely into our email.  In more general terms this means we might be searching through an array to pick out the best fitting information
  • At other times we might decide we want all of the information from the array to be used in our output - so we might loop through and use values from all of the elements in the array.
  • We might also want to go through the array and add up values or make averages, so use some data which is derived from all of the element in the array

To loop through arrays we will use the liquid ‘for’ keyword (more on this here: https://help.shopify.com/en/themes/liquid/tags/iteration-tags).

To get all of the image URLS as output we can use the following script:

This is looping through each of json.images.   Everything between {% for %} and {% endfor %}  will be repeated for each element in the array - this is the loop.   ‘image’ after ‘for’ means that  inside the loop ‘image’ will be the name used for the current element in the array.  So image will be the first image the first time the loop is run, the second image the second time it is run, and so on.

The result of running this script is all of the possible image urls, each on a new line:

Now let’s assume we only want the urls for the images with TABLET_LANDSCAPE in the URL.  We can modify the loop logic as follows:

{%- for image in json.images -%}
{%- if image.url contains 'TABLET_LANDSCAPE' -%}
{{image.url}}
{%- endif -%}
{%- endfor -%}

Running this gives the following output:

If we only want the last one of these we can use a variable to store the url - using liquid’s {%assign%}  keyword to create the variable. Instead of outputting each variable we save it to the variable:

{% assign url = "" %}
{%- for image in json.images -%}
{%- if image.url contains 'TABLET_LANDSCAPE' -%}
{% assign url = image.url %}
{%- endif -%}
{%- endfor -%}
{{url}}

Each write to the variable overwrites the previous value and so we end up with the url from the last image that contains ‘TABLET_LANDSCAPE’.  

If instead we want the first value:

{% assign url = "" %}
{%- for image in json.images -%}
{%- if image.url contains 'TABLET_LANDSCAPE' and url == '' -%}
{% assign url = image.url %}
{%- endif -%}
{%- endfor -%}
{{url}}

Here the if statement has been modified with an extra condition, meaning that once we’ve found a URL we no longer overwrite our variable.  We get the first image:

Instead of using the name we can use the image dimensions:

So now we will keep a variable of the closest match so far, and if an image is a better match, we will update the url.

{%- assign url = "" -%}
{%- assign best_difference_so_far = 9999 -%}
{%- assign desired_width = 800 -%}
{%- for image in json.images -%}
{%- assign this_image_difference = image.width | minus: desired_width | abs -%}
{%- if this_image_difference < best_difference_so_far -%}
{% assign url = image.url %}
{% assign best_difference_so_far = this_image_difference %}
{%- endif -%}
{%- endfor -%}
{{url}}

This example is using maths filters (| minus  and  | abs ), which are documented in more detail here: https://help.shopify.com/en/themes/liquid/filters/math-filters

Also it’s important to use whitespace control tags with feeds, as newlines can cause a lot of problems if a feed result ends up being used in an html attribute - e.g.  the src attribute of an image tag: https://shopify.github.io/liquid/basics/whitespace/

Extracting HTML

Feeds can be used to get content from ordinary HTML web pages.   The fetched page can be accessed through the liquid doc object, as follows:

On the test tab this looks like: 

This returns the entire HTML document.  To extract content from the HTML document there are 3 helpers that can be used:

Tag Stripping:

Liquid’s standard ‘strip_html’ filter can be useful when working with HTML documents: https://shopify.github.io/liquid/filters/strip_html

HTML

In this example we will get the Biography Text from the Taxi for Email Twitter.

Feed set up

Data Extraction

First open the twitter page in a browser, then using the ‘inspect’ tool in the browser find the element we’re looking for:

We can see that the text is in a <p> tag with the class ‘ProfileHeaderCard-bio’.  We can use this to make the following CSS selector:

p.ProfileHeaderCard-bio

We can get the content of this P through the doc object, using the find_first_by_css filter:

This gives the following result:

If we want just the text from this, without html tags, we can add the strip_html  filter:

{{doc | find_first_by_css: 'p.ProfileHeaderCard-bio' | strip_html }}

Which gives just the text:

Did this answer your question?