I have a store on Shopify that I am trying to fix. The customer sells shoes and lists their shoes as ‘UK Size 1, UK Size 2, UK Size 3’ etc. The issue is the shoe sizes for ‘UK Size 10’ sits between the UK Size 1 and UK Size 2 options. I’m assuming this is because it knows it has a number 1 in it, so it’s trying to order it correctly. The problem is, this doesn’t work for our store.
I have tried to adjust the options of the filters using sort, sort_natural etc but to no avail.
Code Snippet
{%- for filter_value in filter.values | sort: 'asc' -%}
{%- capture filter_value_id -%}@@@@-{{ filter_value.param_name | append: filter_value.value | handle }}{%- endcapture -%}
<li class="Linklist__Item">
<input class="Linklist__Checkbox u-visually-hidden" id="{{ filter_value_id | escape }}" type="checkbox" name="{{ filter_value.param_name }}" value="{{ filter_value.value }}" {% if filter_value.active %}checked{% endif %}>
<label for="{{ filter_value_id | escape }}" class="Text--subdued Link Link--primary">
{{- filter_value.label }} ({{ filter_value.count -}})
</label>
</li>
{%- endfor -%}
How it currently looks: https://blockp.co.uk/collections/shoes
You can see how the options are listed like:
UK 1.5 PS (1)
UK 10 (16)
UK 10.5 (12)
UK 11 (18)
UK 11.5 (7)
UK 12 (5)
UK 13 (2)
UK 13.5 PS (1)
UK 2 PS (1)
UK 3 (4)
UK 3.5 (9)
UK 3.5 GS (1)
UK 4 (5)
UK 4 (GS) (1)
UK 4.5 (8)
UK 4.5 (GS) (1)
UK 4.5 TD (2)
UK 5 (4)
UK 5 (GS) (1)
UK 5.5 (7)
UK 6 (25)
UK 6.5 (17)
UK 7 (26)
UK 7.5 (42)
UK 7.5 QS TD (1)
UK 8 (47)
UK 8.5 (34)
UK 8.5 TD (1)
UK 9 (34)
UK 9.5 (25)
The sizes 10, 11, 12, 13 etc all need to be at the bottom.
Any help with this would be majorly appreciated.
2
Answers
Sorting an array of numbers correctly in liquid just doesn’t seem possible, at least it’s not straightforward.
Liquid only seems to sort array elements as strings, meaning it looks at what the string starts with and then sorts according to that, for instance 1 comes before 2, so 10 is considered to be less than 2 or 3.5.
So, to sort an array of numbers correctly in liquid, some maneuvering needs to be done depending on each case.
One way to handle this case would be as follows:
All shoe sizes are either a whole number (2, 3, 7, 11 …), or a .5 decimal (2.5, 9.5, 10.5, …). They’re also all less than 100 (their biggest whole number is no more than 2 digits)
Now the sorting issue, in this case, is due to the fact that some sizes have a 2-digit whole number, or have a floor (a method used to round off the number passed as a parameter to its nearest integer in a downward direction of rounding) that consists of 2 digits, while other sizes have a floor of 1 digit.
So, if we can separate these 2 sets of sizes into their own arrays, sort those 2 arrays individually, and then combine the 2 arrays into 1 array (with the array of smaller sizes first), then the resulting array should consist of the correct sorting of all sizes.
Here’s a piece of code that will do just that:
The resulting sorted_array is:
And now the rest of your code can be applied to it:
in your case, you need to use a special syntax to control the order in which the options are sorted. This is called "natural sorting" and it will treat the strings as numbers.
‘map’ filter is used to extract only the values from the filter object, and then using the ‘sort_natural’ filter to sort the values.
also a ‘downcase’ filter is added followed by a ‘replace’ filter to remove the ‘UK’ and ‘PS’ strings from the size label. you can remove it if you want to or modify as per your needs