Liquid Tutorial 3 - Creating Liquid objects and accessing their properties
The parse_json tag can be used to create objects from a JSON string. These allow you to represent complex entities with properties, instead of using a bunch of separate variables. Dot notation is a useful way to access those properties later.
Written By Matt Jones
Last updated About 1 month ago
Introduction - Objects in Liquid
In a previous article, we introduced Liquid variables and the types of data that can be stored within them. We briefly mentioned Objects, and now is a good time to look at them in more detail.
In programming, we can get so far with a String or Number, but eventually we need to represent some object in the real world that is more complicated, e.g. a person or a product.
Imagine we had two car products, we could represent them with lots of variables:
Example{% assign car_1_make = "Ford" %}
{% assign car_1_model = "Escort" %}
{% assign car_1_reg = "FV62 4GH" %}
{% assign car_1_make = "Ford" %}
{% assign car_1_model = "Prefect" %}
{% assign car_1_reg = "FV32 E4F" %}This could get very messy and hard to manage. It’s better to use objects.
You may already be familiar with Objects, JSON and dot notation from other languages such as JavaScript. Liquid works similarly, but keep your eye out for differences.
Creating Objects in Liquid
You can use the | parse_json filter or the parse_json tag to create Liquid Objects (sometimes called Hash Objects) from literal JSON String representations. Using the example above, we’ll show two methods respectively for creating an object for the car:
Example{% capture car_1 %}
{
"registration": "FV62 4GH",
"make": "Ford",
"model": "Escort"
}
{% endcapture %}
{% assign car_1 = car_1 | parse_json %}
{{car_1 | json }}
{% parse_json car_2 %}
{
"registration": "FV62 4GH",
"make": "Ford",
"model": "Escort"
}
{% endparse_json %}
{{car_2 | json }}Things to notice:
Now the properties are inside objects, they are better organised than loose variables in the previous examples.
Inside the tags, whether the
capturetag, or theparse_jsontag, we are writing a string of characters, using a special format called JSON. JSON is very useful and is used across many computer languages as a common form of writing objects and arrays so that they can be transferred between languages (and can also be easily read by humans).To write an object in a JSON formatted string, we need:
Single curly braces to define a new object
Double quotes
“(strictly) to define a property key e.g. registration, followed by a colon:A value, which needs double quotes for Strings, or no quotes for Booleans, Integers, or Floats
Commas in between properties, but strictly never on the last line!
For readability, it’s often helpful to add newlines and tabs to indent properties to the right of the object brackets. Though these do not have a functional purpose.
Parse is another word for read.
parse_jsonmeans to take a JSON string and read it so that the Liquid can understand it as an object. Only then can we later conveniently access its properties. This is actually the opposite of the| jsonfilter we have been using, which converts a Liquid variable back to a JSON String representation which can be output on the page or transferred to another web service like an API call.The 1st method has an unnecessary extra step of first capturing a String, then coercing it to an Object type. See the previous tutorial: Liquid Tutorial 2 - Liquid variables and types The 2nd method is quicker.
As JSON is a common format, it’s easy to learn more about it online. When debugging, check for commas and quotes in the right place.
Accessing Data in Liquid Variables
Now you know how to create a Liquid Object variable, how can we use it and access its properties?
For example, what if we want to access the car’s registration number?
Example{% parse_json car_2 %}
{
"registration": "FV62 4GH",
"make": "Ford",
"model": "Escort"
}
{% endparse_json %}
{{car_2 | json }}
The car's registration is {{car_2.registration}} and its model is {{car_2.model}}We simply output the variable which stores the object, then use a dot (otherwise known as a period or full stop ) . followed by the key of the property e.g. registration.
Accessing Unusual Property Keys
Sometimes an Object will have keys that contain spaces or other special characters; in this case, simply using dot notation as above will cause ambiguity and confusion as it will interfere with our syntax:
Example{% parse_json car_2 %}
{
"registration plate": "FV62 4GH",
"make": "Ford",
"model": "Escort",
"S.K.U.": "fse4f484tjg"
}
{% endparse_json %}
The reg is {{ car_2.registration plate }} and the SKU is {{ car_2.S.K.U. }}
The reg is {{ car_2['registration plate'] }} and the SKU is {{ car_2['S.K.U.'] }}The first output line doesn’t work. We need to use a variation on the syntax with square brackets and single quotes to access the “keyed index”, see the second line.
This Liquid is useful when you are accessing a WebApp 'collection', creating a Categories layout, using a custom GraphQL query and more.
Chaining
Sometimes Objects will contain other Objects, and you need to drill down deeper to get to the property you need. To do this, you can chain dot notation.
You can think of objects in pOS and Siteglide as a Tree. The Object you start on like context or this is like the root of the tree. Each time you use a dot to access a property, you are going up a branch of the tree and reaching a new set of options for which branch you follow next.
Example{% parse_json car_2 %}
{
"registration": "FV62 4GH",
"make": "Ford",
"model": "Escort",
"style": {
"color": "red",
"hubcap_type": "plastic",
"upholstry_color": "black"
}
}
{% endparse_json %}
The car's colour is {{car_2.style.color}}Another way to do the same thing would be first to create a style Object variable, then access the colour using that:
Example{% parse_json car_2 %}
{
"registration": "FV62 4GH",
"make": "Ford",
"model": "Escort",
"style": {
"color": "red",
"hubcap_type": "plastic",
"upholstry_color": "black"
}
}
{% endparse_json %}
{% assign style = car_2.style %}
Colour = {{style.color}}While in this case this is slower, this technique can be a useful shortcut if you need to access lots of properties of the style object - it saves you writing car2. multiple times.
How to Find the Property you need in a Large Object
In the examples so far, the JSON Object has been created by us in the Liquid tag at the beginning so we know its properties and can look back and read it easily.
However, in Siteglide, you will often come across a large useful Object such as this or context which contains lots of useful properties, but you won’t necessarily know the names of the properties or how deep they lie.
To explore an Object:
Output the object on the Page to get the JSON string
Format that JSON String to make it more easily readable
Here is a simplified version of the context Object, available on all Siteglide Pages. Even with many properties removed, the output (Minified Tab) is hard to read. That's because whitespace is removed for efficiency reasons. Adding the whitespace back in will allow us to read it more easily (see the next section).
Example{"session":{"language":"en","currency_object":"{\"code\":\"GBP\",\"code_lowercase\":\"gbp\",\"symbol\":\"£\"}","tax_code_object":"[{\"id\":\"53\",\"currency\":\"GBP\",\"code\":\"VAT\",\"percentage\":\"20\"}]"},"csrf_request_valid":true,"current_user":null,"headers":{"QUERY_STRING":"","REQUEST_METHOD":"GET","REQUEST_URI":"/test","HTTP_HOST":"mj-page-editable.staging.oregon.platform-os.com","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36","HTTP_ACCEPT_ENCODING":"gzip, deflate, br, zstd","HTTP_ACCEPT_LANGUAGE":"en-GB,en-US;q=0.9,en;q=0.8","HTTP_PRIORITY":"u=0, i","HTTP_SEC_CH_UA":"\"Google Chrome\";v=\"143\",\"Chromium\";v=\"143\",\"Not A(Brand\";v=\"24\"","HTTP_SEC_CH_UA_MOBILE":"?0","HTTP_SEC_CH_UA_PLATFORM":"\"Windows\"","HTTP_SEC_FETCH_DEST":"document","HTTP_SEC_FETCH_MODE":"navigate","HTTP_SEC_FETCH_SITE":"none","HTTP_SEC_FETCH_USER":"?1","HTTP_X_AMZN_TRACE_ID":"Root=1-69553adc-5408592b083edee348cc66b4","HTTP_X_FORWARDED_FOR":"82.12.253.142, 10.100.20.122","HTTP_X_FORWARDED_HOST":"mj-page-editable.staging.oregon.platform-os.com","HTTP_X_FORWARDED_PORT":"443","HTTP_X_FORWARDED_PROTO":"https","HTTP_X_FORWARDED_SERVER":"traefik-6f46cfd859-4dlnf","HTTP_X_REAL_IP":"10.100.45.345","SERVER_NAME":"mj-page-editable.staging.oregon.platform-os.com","SERVER_PORT":"443","PATH_INFO":"/test","skylight.request_id":"2bbcbd81-b2b2-4e74-8de0-56816ea93182"},"params":{"slug":"test","format":"html"},"language":"en","environment":"staging","is_xhr":false}
Looking at the “Formatted JSON” tab, its a little easier to see how we might access the user’s IP address, because now the indentation allows us to see that the relevant HTTP_X_REAL_IP property lies inside the headers property of the main object:
Access the object by variable name
Add a dot, and access the headers property by its key
Add a dot and access the HTTP_X_REAL_IP property by its key
Example{{ context.headers.HTTP_X_REAL_IP}}Formatting the Object "Tree" for readability
To make sense of the JSON that the Liquid outputs, you'll need a tool for automatically formatting the JSON data and adding whitespace. Some tools even help you visualise the data in other more advanced ways.
While there are many tools which can format JSON, the following video shows how it can be done in the Cursor IDE, with the Pretty JSON 3rd party extension. The instructions would work equally well for the VSCode IDE.
We'd recommend when parsing JSON using third party web-based tools that you do not use sensitive Client data. Carrying out the formatting in your IDE is much more secure and a better choice for formatting real data.
Accessing Arrays
When you are accessing data and you reach an array (a list of data), you hit a new kind of choice. You are not able to immediately access properties, because you need to first specify which item of the Array you need. We’ll cover this in the next tutorial.