Solved

Can we SORT collections using SORT_BY in Liquid?!

cfc_webmaster
Explorer
47 0 108

So...

Seems to me this should work... lol

 

{% assign products = selected_collection.products | sort_by: 'price-descending' %} 

But it does not...

 

based on the documentation here, I think I have deeply misinterpreted what this means:

https://shopify.dev/api/liquid/objects#collection-sort_by

 

So I figured I would try to SET the default_sort_by

https://shopify.dev/api/liquid/objects#collection-sort_by 

 

{% assign products.default_sort_by = 'price-descending' %} 

 

nope... cant do that either. lol

 

So...

Am I correct here in the following conclusions:

 

CONCLUSION #1: 

There is NO WAY to change the SORT_BY nor the DEFAULT_SORT_BY for a collection array using either of those objects... (seems tragic to me)

- I feel I must be doing it wrong

Perhaps I have been spoiled by all the wonderful array sorting options available in OOP's like PHP

 

CONCLUSION #2: 

The ONLY WAY I can sort in Liquid is by using the ARRAY FILTERS

https://shopify.dev/api/liquid/filters#sort

 

Which means I have to do this:

price-ascending (low to high)

{% assign products = selected_collection.products | sort: 'price' %} 

price-descending (high to low)

{% assign products = selected_collection.products | sort: 'price' | reverse %} 

title-ascending (A-Z)

{% assign products = selected_collection.products | sort: 'title' %} 

title-descending (Z-A)

{% assign products = selected_collection.products | sort: 'title' | reverse %} 

created-ascending

{% assign products = selected_collection.products | sort: 'created_at' %} 

created-descending

{% assign products = selected_collection.products | sort: 'created_at' | reverse %} 

sort_by=manual

 Simply do not sort in Liquid

sort_by=best-selling

 No such thing in Liquid

sort_by=inventory

No such thing in Liquid
(only possible using first_available_variant.inventory_quantity inside of an elaborate for/loop)

However, I could do this 1 new thing... 

https://shopify.dev/api/liquid/objects#product 

Sort by ID - lol 😛

seems legit and useful...

{% assign products = selected_collection.products | sort: 'id' %} 
{% assign products = selected_collection.products | sort: 'id' | reverse %}

 

As such, if I want to create a drop menu in a featured collection section module 

to let the theme user pick the sorting option for a segmented collection

I would need a really long if/else conditional statement to correctly cover all those options (above) instead of a simple drop menu that assigns a clean variable like this

{% assign products = selected_collection.products | sort_by: section.settings.custom_sort %} 
I presume this is impossible
I must instead use the items (above) in a long overly elaborate conditional statement [yuk] :(
Instead of giving the theme user a simple section setting drop menu (that matches default_sort_by)
I must remap all of these concepts into the Liquid array filter (and skip best-selling)

###

 

Are my conclusions correct and true here?

Or... am I just doing this wrong?

Am I doing this in the stupidest way possible because I do not understand the sort_by feature? 

 

Accepted Solution (1)

PaulNewton
Shopify Partner
6339 579 1343

This is an accepted solution.

.sort_by property is a read-only string.

 

Liquid is a template engine, not an OOP like PHP.

As a language it is a platform DSL with a narrow scope; reign in expectations.

It READS data provided by the system it cannot and will not modify the backend behavior in the way you are trying.

Almost all objects and properties are READ only inside liquid.

You can make variables, change the values of variables but you cannot for instance actually modify the product object on a product page. You can make even a variable named "product" and assign it different products but you never actually modify the underlying objects themselves.

 

Something like sort_by is dictated by two locations: the backend collection sorting a merchant/app/api sets, and the frontend url parameters a client-side user sets from a predefined list of sort option values. Liquids just in the middle doing as it's told. 

 

The only "exception" to this is frontend client side form fields like  , cart attributes and line item properties,  and query parameters like ?sort_by which is then reading that  user preference to make the backend give liquid different data. Naturally this means on the client-side it can be used with ajax apis.

 

Look at the dawn reference theme and it's sort picker for seeing how to dictated the sort order from the clientside.

https://github.com/Shopify/dawn/blob/main/sections/main-collection-product-grid.liquid#L32 

https://github.com/Shopify/dawn/search?q=sort&type=code

https://shopify.dev/themes/architecture/templates/collection#sort-products-in-a-collection 

 

if I want to create a drop menu in a featured collection section module to let the theme user pick the sorting option for a segmented collection

Just provide instructions in the setting to change the sort-order on the colleciton itself, or duplicate the collection and give the duplicate a different sort-order. Otherwise if the settings "sort-order" is different from reality you need to fetch the colleciton on the client-side with the sort_by url parameter.

 

Save time & money ,Ask Questions The Smart Way


Confused? Busy? Get the solution you need paull.newton+shopifyforum@gmail.com


Problem Solved? ✔Accept and Like solutions to help future merchants

Answers powered by coffee Buy Paul a Coffee for more answers or donate to eff.org


View solution in original post

Replies 4 (4)

PaulNewton
Shopify Partner
6339 579 1343

This is an accepted solution.

.sort_by property is a read-only string.

 

Liquid is a template engine, not an OOP like PHP.

As a language it is a platform DSL with a narrow scope; reign in expectations.

It READS data provided by the system it cannot and will not modify the backend behavior in the way you are trying.

Almost all objects and properties are READ only inside liquid.

You can make variables, change the values of variables but you cannot for instance actually modify the product object on a product page. You can make even a variable named "product" and assign it different products but you never actually modify the underlying objects themselves.

 

Something like sort_by is dictated by two locations: the backend collection sorting a merchant/app/api sets, and the frontend url parameters a client-side user sets from a predefined list of sort option values. Liquids just in the middle doing as it's told. 

 

The only "exception" to this is frontend client side form fields like  , cart attributes and line item properties,  and query parameters like ?sort_by which is then reading that  user preference to make the backend give liquid different data. Naturally this means on the client-side it can be used with ajax apis.

 

Look at the dawn reference theme and it's sort picker for seeing how to dictated the sort order from the clientside.

https://github.com/Shopify/dawn/blob/main/sections/main-collection-product-grid.liquid#L32 

https://github.com/Shopify/dawn/search?q=sort&type=code

https://shopify.dev/themes/architecture/templates/collection#sort-products-in-a-collection 

 

if I want to create a drop menu in a featured collection section module to let the theme user pick the sorting option for a segmented collection

Just provide instructions in the setting to change the sort-order on the colleciton itself, or duplicate the collection and give the duplicate a different sort-order. Otherwise if the settings "sort-order" is different from reality you need to fetch the colleciton on the client-side with the sort_by url parameter.

 

Save time & money ,Ask Questions The Smart Way


Confused? Busy? Get the solution you need paull.newton+shopifyforum@gmail.com


Problem Solved? ✔Accept and Like solutions to help future merchants

Answers powered by coffee Buy Paul a Coffee for more answers or donate to eff.org


cfc_webmaster
Explorer
47 0 108

Paul, Thank you. Excellent reply here.

I jumped into Liquid with some unreasonable expectations, the links you have provided here are helpful. *cheers!

ErSanjay
Shopify Partner
307 20 44

@cfc_webmaster 

I have try the code but it was not working as of now do you have any further clarification?

 

this code for the getting the product from the collection
option 1
{%- for product in collection.products |'sort_by=inventory' -%}

option 2
{%- for product in collection.products | sort: 'available' -%}

 

 

Error I am getting into the theme kit CLI.

 

 

main-collection.liquid) Liquid syntax error (line 217): Expected end_of_string but found pipe in "product in collection.products | sort: 'available'"



Business Owner & Shopify Plus, Shopify app , Shopify Consultant - Full Stack Sofware Engineer
Warm regards,
Er Sanjay

If you find yourself in need of assistance with your store, don't hesitate to reach out! Feel free to send me a direct message, and I'll do my best to help you out.
PaulNewton
Shopify Partner
6339 579 1343

@ErSanjay  a filter does not work inside a for loop tag 

You need to pre-assign to a variable that collection with the filter.

Then use that variable in the forloop.

 

{% assign available_collection = collection.products | sort: 'available' -%)
{%- for product in available_collection  -%}
 ...

 

Making sure you look through the dev docs to understand what an "available" product means in shopify liquid. https://shopify.dev/docs/api/liquid/objects/product#product-available

 

Save time & money ,Ask Questions The Smart Way


Confused? Busy? Get the solution you need paull.newton+shopifyforum@gmail.com


Problem Solved? ✔Accept and Like solutions to help future merchants

Answers powered by coffee Buy Paul a Coffee for more answers or donate to eff.org