Skip to content
Malouf Developer Docs

Liquid - All the Things

Welcome to the wonderful (mehhh…) world of Shopify development! According to Shopify, Liquid is a template language or template engine. They use both definitions interchangably. For our purposes, Liquid acts as middleware that bridges the gap between HTML (as well as CSS and JS with the right file extension) and Shopify store data. In this section I will cover some basic Liquid syntax, and how it is incorporated into the Shopify theme.

Syntax

Liquid has a fairly basic syntax that is required in order to render properly. It uses dot notation for objects and their data items. Some properties (designated with plural naming) with return an array of data from the Shopify store. Singular properties will return strings.

Before we get into looping, here are some brief rules to remember about Liquid:

  1. Any file using Liquid needs a .liquid file extension to be read by the template engine. This includes JS and CSS/SCSS if you are using Liquid variables inside external files. However, if you are using Liquid inside a file with a basic style block, it would look something like below.
{% style %}
  .container {
    padding: {{ section.setting.bottom_padding }};
  }
{% style %}
  1. To indicate output use double curly brace delimiters.
<p>To see more products like the {{ product.title }}, visit our influencer page.</p>
  1. To indicate logic use curly places with percentage symbols {% ... %}. This includes something as simple as leaving a comment in a Liquid.
{% comment %}
  This is an example comment in Liquid
{% endcomment %}

Data Output

Despite its unique syntax, Liquid does have a lot of nice built-in filters and functions. For example, say you want to access the product object but you aren’t certain of what values are available to you. With Liquid filters you can easily print JSON objects to the screen.

  Product object: {{ product | json }}

Story time! In one particular instance, I needed to match unique background images to each menu item. I decided to add the image to the theme asset folder since Shopify’s navigation API has limited data inputs. This is what I came up with:

 <div class="list-menu__image"
      style="background-image: url(
        {{ link.title | downcase | remove: " " | escape | append: '-nav.png' | strip | asset_url }}
        );">
  </div>

Using some Liquid functionality, the above code section is taking the link name, making it lowercase and removing any spaces. The pipe | is Liquid’s default separator. I’ve added escape to replace characters with escape sequences so the string can be used in a URL. After those changes to the link name, we then append the file extension and strip out any access whitespace from the beginning and end of the string. Finally, we use the asset_url filter to populate the full URL path since the image should be stored in the “assets” folder. Shopify development requires pretty extensive use of the URL filters. You can read more documentation here.

Loops

Thanks to Vue, we are all pretty familiar with loops which makes Liquid pretty easy to grasp. Aside from the slight change in syntax the for loops are very similar.

{% for product in collection.products %}
  {{ product.title }}
{% endfor %}

In the above code we are looping through all the product titles in the product collection.

Much simple. So iteration.

Output would look something like this:

Big Ole' Couch Queen Mattress Duvet Cover Pillow Pet

Loops can be nested. You could even use Liquid syntax to loop through items in a JS file, if you felt the urge. Just make sure that .liquid extension is present. The github docs for Shopify Liquid has some basic examples and covers various usages of the for loop.

Logic

Ever done an if statement? In that case, you already have a great grasp on logic in Liquid. As previously stated, the only real difference will be the syntax.

  {% if cart.item_count > 0 %}
  <p>You have {{ cart.item_count }} item(s) in your cart</p>
  {% else %}
    <p>There's nothing in your cart</p>
  {% endif %}

A key point to remember is that instead of elseif, Liquid used elsif. No e…for reasons? Otherwise elsif works exactly the same.

Another popular logic statement in Liquid the “case/when” tags. Case/when is basically a switch statement to compare a variable with different values.

  {%- case item.object_type -%}
    {%- when 'product' -%}
      {% render 'card-product', card_product: item %}
    {%- when 'article' -%}
      {% render 'article-card', article: item %}
    {%- when 'page' -%}
      <div class="wrapper">
        <div class="page__badge {{ section.settings.badge_position }}">
          <span class="page__badge">{{ 'templates.search.page' | t }}</span>
        </div>
      </div>
  {%- endcase -%}

In the code block above you can see that we are displaying (rendering) different HTML snippets based on the item object. This is more complex example, but some things to note is that the case/when statement starts with {% case %} and ends with {% endcase %}. For the when sections, we are just looking for a basic value and using Liquid’s {% render %} method to display a snippet.

Wait, what is a snippet you ask?? Well, you can think of a snippet as a component. You can include it in Shopify sections (or modules as I like to call them), and it will be populated with values from that module like in cart_product: item. If you inspect the HTML inside the {%- when 'page' -%}, you will see we are adding a class based on the section settings for the badge position. This would be set up through the JSON schema in the section. In the place of the badge, we are looking in the translations file for the value of templates.search.page and display the text with the filter | t . Phew, so much explanation for so little code.

Variable Assignment

In Liquid you can create variables in a few different ways. There is no const or let unless you are in a script tag.

  1. Assign Think of assign as the let of Liquid.
  {% assign ratio = 2 %} // number
  {% assign product = "couch" %} // string
  {% assign show_mobile = false %} // boolean
  1. Capture Capture is used to assign complex strings to a variable. Capture should be used if you have other Liquid values in a string.
  {% capture related_product %}
    To see more products like the {{ product.title }}, see our other {{ product.type }} <a href="{{ category.url }}">here</a>.
  {% endcapture %}
  1. Increment/decrement For a variable being used as a counter you would use increment or decrement.
 {% increment cart_counter %}
 {% decrement cart_counter %}

Liquid Stacking

One last thing I would like to cover about Liquid is that you can stack logic instead of using multiple {% ... %} tags. This is helpful if you are making variable assignments based on nested if statements or loops. Ready for a complex example that I probably won’t explain very well? Here you go!

{%- liquid
  if use_variant
    assign target = product.selected_or_first_available_variant
  else
    assign target = product
  endif

  assign compare_at_price = target.compare_at_price
  assign price = target.price | default: 1999
  assign available = target.available | default: false
  assign money_price = price | money
  if settings.currency_code_enabled
    assign money_price = price | money_without_trailing_zeros
  endif

  if target == product and product.price_varies
    assign money_price = 'products.product.price.from_price_html' | t: price: money_price
  endif
-%}

I pulled this right off a Shopify theme product page. If this doesn’t make any sense, no worries. The main thing you should notice is the opening and closing tags. When you use a dash {%- ... -%} in Liquid brackets, it means you want to strip the excess whitespace from variables (but keeps spaces in-between string characters). If you start the tag with a dash, remember to close it otherwise Liquid won’t recognize it was a true closing tag. Another thing to note is that we don’t need to include other brackets when within a Liquid block. Just make sure to indent properly so the template engine can know what is a single line versus what is inside a logic statement. It makes for code that is easier to write as well as easier to read.

Additional Resources

Now that your brain is surely on fire, here are a few additional resources for your Liquid journey. The best way to learn to swim in Liquid is to leap in head-first and hope there isn’t a strong current. Perhaps choose a smaller pool, or in this case a pre-made theme, to get used the layout and sytnax before venturing out in open water.