Exploring the Liquid Templating Language

Hero image for Exploring the Liquid Templating Language.
Hero image for 'Exploring the Liquid Templating Language.'

Liquid is a Rubybased, opensource templating language developed by Shopify and released in 2006. Its inception was driven by the need for Shopify to offer a flexible and safe environment for both developers and users on the Shopify platform, the need to provide a way for users to develop customised ecommerce storefronts without compromising on the security or performance of the platform itself.

For us as frontend developers, understanding and working with Liquid is essential if you're looking to develop a bespoke ecommerce site using the Shopify platform. It embodies the connection between static content and interactive web elements, which allows us to produce secure, efficient, and tailored online shopping experiences for our clients and their users.


Understanding Liquid

For me, my first introduction to the syntax Liquid uses felt very similar to Handlebars. However, the deeper you get into the development process, the larger the separation you see between the two.

Running Liquid Locally

To work locally with Liquid templates, you're going to need to set up a Ruby environment. There are two possible routes to take: the Shopify Theme Kit, or the Shopify CLI (I'll cover these both a little more below). Both provide you with a set of commandline tools that you can then use to develop, manage, and test your Shopify themes locally.

Use Shopify's Theme Kit

Shopify Theme Kit has begun to be been replaced by Shopify CLI now, but if you're working with existing or older templates, then this is easy with Homebrew:

brew tap shopify/shopifybrew install themekit

Use the Shopify CLI

Unless you're adopting an existing codebase, then I would recommend working with the Shopify CLI instead. It is intended to replace Theme Kit outright going forward, so it is likely to be the more futureproof option. It also natively supports Apple silicon (i.e., the M1 architecture, which is something I've grappled with before), so overall, I'd recommend this route over Theme Kit unless you're working with an older template.

The installation process is a little more involved than just running a couple of Homebrew commands though, so rather than attempt to replicate those here, I'll signpost you through to the official documentation on how to install Shopify CLI.

Some Basic Code Examples

There are a lot of features in Liquid, so trying to cover much more than an overview in my examples would lead to a very long (and very dull) article. So, I'm including a few basics below, but encourage you to go and take a look at the documentation to get a firmer grasp of just how much Liquid is capable of.

For now, some simple code examples:

Outputting a Variable

I've mentioned the similarities to Handlebars before, so this might feel familiar to those of you who've used Handlebars in the past. If you have an object called product with a field called title, then you would output it into your template like this:

{{ product.title }}

Using a Filter

Liquid comes with quite a few filters out of the box, all of which are applied in the same way using the pipe (|). So, for example, to use the date filter to format the current date:

{{ 'now' | date: "%Y-%m-%d" }}

This will output the current date in the format YYYYMMDD, i.e.: 20190502.

Iterating Over Data

Much as you'll likely be familiar with from other templating languages, implementing a loop in Liquid looks like this:

{% for product in collection.products %}  {{ product.title }} - {{ product.price | money_with_currency }}{% endfor %}

Compatibility with JavaScript Frameworks and CSS Preprocessors

Since very few frontend developers actually write their code by hand any more, I'm sure that compatibility with the likes of Sass or React will be a strong consideration. Fortunately, it is relatively easy to implement these into your Shopify pipeline.

Sass and Less

Neither Sass nor Less are supported directly into Shopify's asset pipeline. However, this is a situation I'm sure we're all familiar with; it's just a case of compiling your CSS using a build tool (webpack, Gulp, etc) and integrating that into the Shopify CLI. You can then include the compiled version in your Liquid templates just like you would any other CSS file, and upload the compiled version as part of your theme:

{{ 'styles.css' | asset_url | stylesheet_tag }}

React

Really, it is a similar story when it comes to using frontend JavaScript frameworks like React in conjunction with Liquid. To incorporate React into a Shopify theme, you would typically include a new build step in your development process, which involves setting up a separate React application and then bundling it using a build tool like webpack or Create React App.

The React app can then be mounted into a specific element within your Shopify pages, which means you can leverage the componentbased architecture of React for dynamic/interactive features in particular, like the image carousels and product configurators you would commonly find on a Product Details Page.

A fairly simplified workflow might then look something like this:

  1. Develop your React app separately, focusing on the interactive UI elements you want to enhance within your Shopify theme.
  2. Compile your React app into static JavaScript files.
  3. Include the compiled JavaScript file within your Shopify theme assets.
  4. Use Liquid to reference your compiled JavaScript file in your theme, and initialise the React app within the desired page elements.

Something a little like this:

<head>  ...  {{ 'bundle.js' | asset_url | script_tag }}</head><body>  <div id="react-app"></div>  <script type="text/javascript">    // Assuming you've called your React application 'App'    ReactDOM.render(<App />, document.getElementById('react-app'));  </script></body>

Using this sort of approach means that you get the best of both worlds: Liquid's serverside rendering capabilities and SEO advantages, combined with React's clientside interactivity.


Features of Liquid in More Depth

I've already gone into some basic code and syntax examples above, so here let's explore some of the core features of Liquid in a little more detail...

Objects and Filters

Objects

In Liquid, objects are placeholders which output dynamic content. They are denoted by double curly braces {{ }} and can represent moreorless anything from strings and numbers to much more complex data structures.

Filters

We use filters to modify the output of objects; these are applied to variables using the pipe character |. There are quite a few filters available; these can be used to transform text, adjust dates, manipulate arrays, and more. This allows us to manipulate and present data without needing to leave the template.

Object and Filter Code Example

As a brief example, below, we are taking the product.title object and outputting it using the upcase filter, which will make it all uppercase:

{{ product.title | upcase }}

Tags for Logic and Control Flow

In Liquid, tags perform logical and control operations directly within the template. They are enclosed with curly braces and percentage signs {% %} and support conditions, loops, variable assignments, and more.

If Statements

As you will be familiar with in other languages, if statements allow us to use conditional logic to decide whether to display content or not.

Loops

Again, as a developer, you will undoubtedly be familiar with loops. These iterate over collections (arrays or objects) and then output in a repeated operation.

If and Loop Code Example

Here's a little snippet from one of my templates that seems to illustrate these quite well. Here, we're checking to see if a user is logged in or not. If they are, then we display their products. If they aren't, then we prompt them to log in:

{% if user.logged_in %}  Welcome, {{ user.name }}!  Here are your products:  <ul>    {% for product in user.products %}      <li>{{ product.name }}</li>    {% endfor %}  </ul>{% else %}  Please log in to see your products.{% endif %}

Drops

Drops are a little more involved than simple template logic, and require a little more indepth knowledge of Ruby to implement. Essentially, a drop is a class in Ruby which Liquid uses to expose specific methods and data to the template. We can use these to manipulate our store data in a secure and controlled manner.

Given that Liquid handles this internally and it equates much more to a backend feature than a templating one, I'll leave it up to you to decide whether to explore these further by looking through the documentation.


Honorary Mention: Jekyll

As a very brief aside and because I can't find anywhere better within this article to share this tidbit of information I found whilst researching this article; although Shopify developed Liquid for its ecommerce platform, it has been adopted by any number of other applications and platforms since.

The most wellknown adopter is Jekyll, the popular opensource static site generator. Underneath the hood, it is the Liquid templating engine that is powering Jekyll and allowing developers to create blogaware static websites.


Wrapping up

As is so often the case, this article has taken a bit of a meander as it progressed. So just to wrap things up: if you want to develop with Shopify, then Liquid is the templating engine you will need to become familiar with. Like any other templating language, it is relatively straightforward to get to grips with, and can be added into an existing (or new) CI pipeline alongside CSS preprocessors like Sass, or JavaScript frameworks like React.

If you've been in web development as long as I have, you might even find that you are already familiar with it already due to it's use in Jekyll.


Categories:

  1. Front‑End Development
  2. Liquid
  3. Shopify