Advanced Arrays in Shopify's Liquid
Liquid is Shopify’s templating language. It’s great and packed with useful helpers. Unfortunately, it struggles when it comes to creating arrays (probably fair, it’s a templating language, afterall).
Creating an array is a simple process, albeit not very intuitive:
{% assign myArray = "item-1|item-2|item-3" | split: "|" %}
We’re assigning a string to a new variable called myArray
. The array is created when we use the split
filter. Now we can run a for
loop on our array:
{% for item in myArray %}
{{ item }}
{% endfor %}
Will output:
item-1
item-2
item-3
Associative Arrays
Now things get a little complicated. Shopify has a great new feature for sorting collections. Instead of creating the dropdown manually, I wanted to create a simple for
loop that looked like:
{% assign sortTitles = "Featured|$ Low to High|$ High to Low|A-Z|Z-A|Oldest to Newest|Newest to Oldest|Best Selling" | split: "|" %}
<select>
{% for title in sortTitles %}
<option value="{{ title | handle }}">{{ title }}</option>
{% endfor %}
</select>
Unfortunately, {{ title | handle }}
does not accurately correspond to the values we need to pass to the URL. I need to tie (or associate) the handle with a front-facing title that anyone could edit. Double array to the rescue!
{% assign sortHandles = "manual|price-ascending|price-descending|title-ascending|title-descending|created-ascending|created-descending|best-selling" | split: "|" %}
{% assign sortTitles = "Featured|$ Low to High|$ High to Low|A-Z|Z-A|Oldest to Newest|Newest to Oldest|Best Selling" | split: "|" %}
<select>
{% for handle in sortHandles %}
<option value="{{ handle }}">{{ sortTitles[forloop.index0] }}</option>
{% endfor %}
</select>
We can use the current loop’s index value and use it to get our title from the sortTitles
array. You just need to make sure that if you reorder any of the items in one array you do the same reordering in the other one.
The final markup, if you’re interested, looks like this:
{% for handle in sortHandles %}
{% if collection.sort_by == blank and collection.default_sort_by == handle %}
{% assign currentTitle = sortTitles[forloop.index0] %}
{% elsif collection.sort_by == handle %}
{% assign currentTitle = sortTitles[forloop.index0] %}
{% endif %}
{% endfor %}
<label class="selected-text">Sort by: <strong>{{ currentTitle }}</strong></label>
<select>
{% for handle in sortHandles %}
{% if collection.sort_by == blank and collection.default_sort_by == handle %}
<option value="{{handle}}" selected="selected">{{ sortTitles[forloop.index0] }}</option>
{% elsif collection.sort_by == handle %}
<option value="{{handle}}" selected="selected">{{ sortTitles[forloop.index0] }}</option>
{% else %}
<option value="{{handle}}">{{ sortTitles[forloop.index0] }}</option>
{% endif %}
{% endfor %}
</select>
There’s quite a bit of JavaScript involved as well, but we’ll save that for another post!