Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 38

Advanced Liquid Filters for Array and Object Manipulation

Recommended resources

Hello and welcome back.

In our last lesson, we focused on handling large datasets by implementing pagination, allowing us to split a big collection of products across multiple pages. That was about managing the quantity of data. Now, we'll shift our focus to manipulating the data itself on a single page.

This lesson addresses the learning outcome: Apply advanced Liquid filters (map, where, sort) to manipulate arrays and objects.

Given your full-stack development background, these concepts will likely feel familiar. They are Liquid's equivalent of JavaScript's powerful array methods like Array.prototype.map(), Array.prototype.filter(), and Array.prototype.sort(). You'll learn how to apply these patterns within Shopify's templating language to create more dynamic, clean, and efficient theme code.

1. The "Why": From Loops to Filters

In programming, we often need to transform, filter, or reorder data. In JavaScript, you might write something like this to get the titles of all available products:

const availableProductTitles = products
  .filter(product => product.available)
  .map(product => product.title);

This is concise and declarative. While Liquid doesn't have anonymous functions, it achieves the same goal using a chain of filters. Instead of verbose {% for %} loops with complex {% if %} conditions inside, we can use array filters to perform these operations more elegantly. This not only makes your code cleaner but can also be more performant, as the logic is handled by Shopify's optimized Liquid engine.

Let's explore the core filters for these tasks.


2. The "How": Manipulating Arrays with where, sort, and map

We'll use a comprehensive guide to walk through these filters. It provides clear explanations and examples for each.

Shopify Liquid - The Ultimate Guide

This guide, 'Shopify Liquid - The Ultimate Guide' by Chris the Freelancer, has an excellent section on array filters. We will use it as our primary reference for this lesson.

Please read the 'Array filters' subsection. Pay special attention to the descriptions and code examples for where, map, and sort. Notice how the guide compares where to a traditional for loop with an if statement—a great illustration of its value.

Let's break down the three key filters from that reading and see how they apply.

A. where: Filtering an Array

The where filter is Liquid's equivalent of JavaScript's filter(). It creates a new array containing only the elements from the original array that match a specific property value.

  • Syntax: {{ array | where: "property", "value" }}

Imagine you want to display a special section for all products made by a specific vendor, say "Peak Performance Gear". Instead of looping through all products and checking the vendor inside the loop, you can do this:

{% comment %}
  Create a new array containing only products where the vendor is 'Peak Performance Gear'
{% endcomment %}
{% assign peak_products = collection.products | where: "vendor", "Peak Performance Gear" %}

{% comment %}
  Now you can loop through this much smaller, pre-filtered array
{% endcomment %}
{% for product in peak_products %}
  <p>{{ product.title }}</p>
{% endfor %}

This is significantly cleaner than the alternative shown in the resource you just read:

{% for product in collection.products %}
  {% if product.vendor == "Peak Performance Gear" %}
    <p>{{ product.title }}</p>
  {% endif %}
{% endfor %}

B. sort: Ordering an Array

The sort filter reorders the elements of an array based on one of their properties. This is perfect for when you need to present data in a specific order that isn't the default, like sorting products by price or title.

  • Syntax: {{ array | sort: "property" }}

By default, sort on strings is alphabetical and case-sensitive (uppercase letters come before lowercase). For numbers, it's ascending. You can chain it with the reverse filter to invert the order.

Shopify Liquid Sort Filter Example
This image shows products sorted from the lowest to the highest price. The accompanying code snippet, `{% assign sorted_products = collection.products | sort: 'price' %}`, demonstrates precisely how the `sort` filter is used to achieve this result.

Here's how you'd implement both ascending and descending price sort:

{% comment %} Sort products from lowest to highest price {% endcomment %}
{% assign products_sorted_asc = collection.products | sort: 'price' %}

{% for product in products_sorted_asc %}
  <p>{{ product.title }} - {{ product.price | money }}</p>
{% endfor %}

<hr>

{% comment %} Sort products from highest to lowest price by chaining 'reverse' {% endcomment %}
{% assign products_sorted_desc = collection.products | sort: 'price' | reverse %}

{% for product in products_sorted_desc %}
  <p>{{ product.title }} - {{ product.price | money }}</p>
{% endfor %}

Note: For case-insensitive sorting on strings, you can use sort_natural. For example, | sort_natural: 'title' would sort "apple", "Banana", "cherry" into the expected order.

C. map: Extracting Data from an Array

The map filter is Liquid's version of JavaScript's map(). It iterates over an array of objects and creates a new array containing the value of a single specified property from each object.

  • Syntax: {{ array | map: "property" }}

This is incredibly useful when you need a list of specific data points. For example, what if you wanted to get a list of all unique tags used across all products in a collection?

{% comment %}
  1. 'map' creates an array of arrays (since each product has an array of tags).
     This step results in something like: [['tag1', 'tag2'], ['tag2', 'tag3']]
  2. 'flatten' is a bonus filter that turns an array of arrays into a single array.
     Result: ['tag1', 'tag2', 'tag2', 'tag3']
  3. 'uniq' removes duplicate values.
     Result: ['tag1', 'tag2', 'tag3']
{% endcomment %}

{% assign all_tags = collection.products | map: 'tags' | flatten | uniq %}

{% comment %} Now you can output the clean list of tags {% endcomment %}
<p>Tags in this collection: {{ all_tags | join: ", " }}</p>

In this example, we chained multiple filters (map, flatten, uniq, join) to perform a complex data transformation in a single, readable line. This is where the true power of Liquid filters becomes apparent.

Test your understanding!

Let's combine these filters. Imagine you have a collection of products and you want to display an alphabetized list of product titles for all available products that cost less than $50.

Write a single Liquid assign statement to create an array named deal_titles that contains the titles of these products.

Hint: You'll need to chain where (twice, once for availability and once for price, although price requires a different approach), sort, and map. Filtering by price is tricky with where, so think about how you might loop and check a condition. For this exercise, let's simplify and just filter by availability, then sort by title.

Challenge: How would you get an alphabetized list of titles for all available products in a collection?

Show answer

Here is the solution to the challenge question:

{% assign deal_titles = collection.products | where: "available", true | sort: "title" | map: "title" %}

Let's break down the chain:

  1. collection.products: Starts with the array of all product objects.
  2. | where: "available", true: Filters this array, keeping only the products where the available property is true.
  3. | sort: "title": Sorts the remaining product objects alphabetically by their title.
  4. | map: "title": Creates a new, final array containing only the title string from each of the sorted, available product objects.

The deal_titles variable now holds a simple array of strings, ready to be displayed.


Conclusion

Today, you've added three powerful data manipulation tools to your Liquid toolkit. By mastering where, sort, and map, you can write more sophisticated, readable, and efficient theme code, moving beyond basic loops to declarative data transformations.

Key Takeaways:

  • Analogy to JavaScript: Liquid filters like where, sort, and map serve the same purpose as JavaScript's filter, sort, and map array methods.
  • where for Filtering: Use where to select a subset of an array based on a property's value, which is cleaner than a for loop with an if.
  • sort for Ordering: Use sort to order an array by a specific object property. Chain it with reverse to invert the order.
  • map for Extracting: Use map to create a new array containing a single piece of data from each object in the source array.
  • Chaining for Power: The real power of filters comes from chaining them together to perform complex data transformations in a concise way.

In our next lesson, we will broaden our focus from these specific techniques to the overall topic of performance. We'll answer the question: Why is theme performance critical for user experience and SEO? You'll learn how to analyze your theme's speed and what factors contribute most to a fast (or slow) Shopify store.