Sort by best selling in shopify liquid - shopify

I want to sort collection products by 'best-selling' but it's not work when i test .
i don't know why. Below is my code
{% assign products = collection.products | sort: 'best-selling' %}
When i sort it with 'price', it work, but with best-selling it's not.I hope someone can help me how to do it

The sort function is a generic sort for array. You can sort by any field of the element in the array. In case of products you can write
{% assign products = collection.products | sort: 'title' %}
because the title (or price, etc) is an attribute of the product.
A product doesn't have any attribute that specify how many units have been sold.
You can change the default sorting method of your collection to 'Best Selling' so that products are sorted that way by default.
Also, you were probably confused by the sort_by function which is quite different
{{ collection.url | sort_by: 'best-selling' }}
gives you the link to the collection page using the given sort function.

Related

Display collection metafield in product page (Shopify)

there is a way to display a collection metafield in the porduct page?
Each product have a product type that matches the collection, so in the product page of this product I want to display the metafield of that product.
{{ collection.metafields.custom.metafield1 }} doesn't work because of course I'm not in the collection page, so I need to link collection.metafields.custom.metafield1 and product.type, but I don't know how.
Hope I was clear, thank you.
Each product have a product type that matches the collection, so in the product page of this product I want to display the metafield of that product.
I solved with the following code
{% assign collectionHandle = product.type %}
{% assign the_collection = collections[collectionHandle] %}
{% assign my_metafield = the_collection.metafields.custom.categoria_1 %}
{{ my_metafield.value }}
As you suggest it was fun to solve the problem :-D
Hard to understand your question, but it would probably go like this. In Liquid, every product has a type. So you would use that on the collections object to get just the collection you want, and from that, the special metafield assigned.
{% assign the_collection = collections['{{ product.type }}'] %}
That assigns some collection, assuming it exists, based on the current product type, to your variable. Now you would ask for your special metafield that may or may not exist in that collection's metafields.
{% assign my_metafield = the_collection.metafields.some_namespace.some_key %}
And with that, you could get the value and splash it out there as you please.
<h1> {{ my_metafield.value }} </h1>
yes I understand your point, and I figure out your code and I tried to use it:
{% assign the_collection = collections['{{ product.type }}'] %}
{% assign my_metafield = the_collection.metafields.custom.categoria_1 %}
<span>{{ my_metafield.value }}</span>
and I don't understand why it does not work.
The product type exists and is "Piatti"
The collection "Piatti" exists and has the metafield custom categoria_1
I attach a sceenshot of the metafield in order to be more cleare.
metafield structure

Modify Shopify search - display product variants, correct pagination

I'm trying to find a way for the following:
I'm modifying a liquid template to also include found product variants on a search result page. But when I do the amount of visible products/product variants on a search results varies greatly and leads to bad UX.
We have a pagination break at 28 items. But this only factors in the amount of products it has already displayed. As I now show variants of the products as well, the pages have a very large amount of items on them. If I decrease the pagination limit to - let's say 4 - I end up with pages that have exactly 4 entries and pages that have let's say 500 entries depending on the matching variations for a given search term.
This is the overall goal:
Display product variants in the search result page as well as the default products and still have a correct pagination that display a fixed amount of products/variants/search result items per page.
My approach was this:
{% capture total_results %}
{%- for result in search.results -%}
{%- case result.object_type -%}
{%- when 'product' -%}
// Go over all the variants and match to the search terms
// Include product-grid-item template in case it matches
{%- when 'article' -%}
{%- when 'page' -%}
{%- endcase -%}
<!-- Divider: #### -->
{%- endfor -%}
{% endcapture %}
{% comment %}Break the captured string at the divider string into an array{% endcomment %}
{%- assign total_results = total_resuls | split: "<!-- Divider: #### -->" -%}
<div class="page__description page__description--centered">
<span>{{ 'search.general.results_count' | t: count: total_results.size, terms: search_terms }}</span>
</div>
{% paginate total_result by 28 %}
{% for result in total_resuls %}
{{ result }}
{% endfor %}
{% endpaginate %}
I get the following liquid error in the frontend: Array 'total_results' is not paginateable.
Is there a way to make it paginateble?
Or is there a way to modify the search.results collection directly so that the pagination doesn't only consider the amount of results from the shopify search but also the variations?
The reason we do this btw is that shopify does seem to find the products based on an information where only the variation matches. But in this case it only links to the product and the user whould need to go to the correct variation manually again which is very bad UX.
Even if the user searches by ID directly they get linked to the normal product page. And we want them to be linked directly to the correct variant that was the reason the product was included in the search results in the first place.
Any help would be appreciated. Or pointers on how else I could achieve this.
Unfortunately, there's no way to paginate through your array. paginate tag can only be used with search.results, collection.products on some other predefined objects.
The way you're trying to implement it doesn't seem possible to me. But here are a couple of ideas came to my mind that might help you:
Option 1. Use search.terms object to build a link to the correct variant. As the main issue is that Shopify search result
links to the product and the user would need to go to the correct variation manually
I would just suggest displaying search results as is but apply your logic from
// Go over all the variants and match to the search terms
to add a ?variant_id=xxx attribute to the search result URL. Then once customers get to the product page, the variant will be selected based on this query parameter. This logic would also perfectly suit the case when customers search by variant ID.
Option 2. Build custom search. It would require more efforts and implies not using the Shopify search at all. You would need to sync store products and return the paginated results from your database based on a query from the search form. This option would give you flexibility in displaying your product results.
I would go with option 1 if the only you want to do is select the correct variant based on the user's search query. But it may not work if you have multiple matching variants and you either want to display all of them separately or be able to redirect the customer to every matching variant from the results page.
P.S. Just a hint: you're using {%- when 'product' -%} block to filter product results only, but you can use ?type=product in your query to search only through products entities, ignoring articles and pages.
Maybe you can try this app https://apps.shopify.com/ultimate-search-and-filter-1 to show variants as separate products on Collection and Search result page without affecting the paginiation in Shopify.

Show products on article

How can I show a list of products (like a recipe) on a article page.
Can you give me some guidance on what should i use to achieve that behavior?
How can i link those products dynamically to the article?
Getting the products once we know what they are
There are two ways to bring up products on an arbitrary page in Shopify:
1) Using all_products[handle]
Using the product handle to get the product from the all_products global object.
Example:
{% assign ingredient = all_products['lavender-oil'] %}
This works well for small numbers of products, but for large numbers of products it may cause delays in page-loading times. We are also limited to only 20 (I think) calls to all_products per page, so this wouldn't work for recipes with a ton of ingredients in them.
2) Using a collection
Use a collection that contains only the products required. You can reference any arbitrary collection if you know the collection's handle. When making collections, you can also sort products manually to control the order that they appear in when you loop through it. Collections can contain an arbitrary number of products, and I believe the default pagination will give you is either the first 20 or 50 products if you don't specify any other limit. If required you can adjust the number of products served to as high as 1000 by wrapping your collection-product loop with paginate tags (though that upper limit is definitely not recommended for performance reasons)
Example:
{% assign ingredients = collections['love-potion-number-9'] %}
{% for product in ingredients.products %}
<h2>{{ product.name }}!!</h2>
{% endfor %}
The downside for both of these is that you can't write Liquid code inside your article content in Shopify, so this ingredients section would need to be written as a snippet or a section in your theme files and included in your article template used for these recipes.
This leads me to consider the next issue - you would want to include a concept of quantity with the ingredients, and so far neither of the above give us that. So now, the hard part:
Getting that information into a Liquid snippet/section in the first place
There are a few different ways that I can think of offhand that would help you out here. No one is perfect, unfortunately.
Using Metafields
Metafields are a great tool available in Shopify, but unfortunately Shopify doesn't make them easy to use [1].
Once you have a metafield-editing tool, come up with a naming structure for the 'namespace' and 'key' values. For example, you might create the following metafields for the recipe you provided. (Note: How these would be entered will depend on what metafield-editing tool you're using)
namespace: 'ingredients', // We'll use this as the 'box' that holds all our ingredients
key: 'juniper-berry-oil', // This will be the product handle for the product in question
value: '2 drops' // The quantity used for the recipe
namespace: 'ingredients',
key: 'rosemary-ct-camphor-oil',
value: '1 drop'
namespace: 'ingredients',
key: 'cypress-oil',
value: '1 drop'
... (etc) ...
Then, in your theme file where you are creating your ingredient list, you would have code that looks something like this:
{% assign ingredients = article.metafields.ingredients %}
{% for ingredient in ingredients %}
{% assign handle = ingredient.first %}
{% assign amount = ingredient.last %}
{% assign product = all_products[handle] %}
<!-- HTML code here -->
{% endfor %}
Using Tags and Products
If you create a tag-naming scheme, you can loop through those and use them to build your ingredient list. For example, if you give the article a number of tags in the form ingredient_[product-handle]_[amount], you would be able to reference them as:
{% for tag in article.tags %}
{% if tag contains 'ingredient' %}
{% assign breakdown = tag | split: '_' %}
{% assign handle = breakdown[1] %}
{% assign product = all_products[handle] %}
{% assign amount = breakdown | last %}
<!-- HTML Code -->
{% endif %}
{% endfor %}
The downside to this method is that there's no easy way to reorder the tags if done this way - using a collection will give you better control of that.
Getting recipe amounts into a Collection loop
The easiest way to reference a collection would be to have a collection with the same handle as the article - then you can reference the collection and its products as:
{% assign ingredients = collections[article.handle] %}
{% for product in ingredients.products %}
<!-- HTML Code here -->
{% endfor %}
This has the advantage of letting you easily sort the ingredients by setting the collection to have a Manual sorting method, but the corresponding downside is that there's no obvious place to put the quantity information.
One way to get that information in would be to use either tags or metafields - metafields would have the advantage of being able to directly access the quantity for the product - if using the naming convention above in the metafields part of this answer, you could use:
{% assign ingredients = collections[article.handle] %}
{% for product in ingredients.products %}
{% assign amount = article.metafields.ingredients[product.handle] %}
<!-- HTML Code here -->
{% endfor %}
If using tags, you would need a format that could be split up like in the tag section and loop through all your tags each time to find the one for your product. If your tags were set up as ingredient_[product-handle]_[amount]
If using tags, you would need a format that could be split up like in the tag section and loop through all your tags each time to find the one for your product. If your tags were set up as the example above:
{% for tag in article.tags %}
{% if tag contains 'ingredient' and tag contains product.handle %}
{% assign amount = tag | split: '_' | last %}
{% endif %}
<!-- HTML Code -->
{% endfor %}
Hopefully this helps you get going!
[1] Using Metafields: There are several possible solutions for editing metafields in Shopify - my personal preference is the 'Shopify FD' extension for Chrome, but the recent updates to the Shopify admin screens are interfering with this extension's ability to load & show its metafield panels on some pages. I know that product pages still work, but some pages (like collections) don't anymore.
There are also a number of apps available for your store to edit metafields - I haven't used any of them, so I can't speak to their value, but you can view the list here: https://apps.shopify.com/search?q=metafield&st_source=
If you have a coding background, you can also create and update metafields yourself by sending the right data to Shopify's Admin API - see the documentation at https://help.shopify.com/en/api/reference/metafield if you want to try doing it yourself.
Here is a sure to succeed recipe. Write your Article. It will have a handle, unique to it. Save that in your head, clipboard, etc. Now create a manual collection. Give it the same handle. Now you can reference an empty collection by the Liquid:
collection['some-handle-to-an-article']
What if you now filled that collection with the products in your recipe? Eureka. Genial! You can then list them in a simple Liquid for next loop like this:
{% for product in collection['some-handle-to-an-article'] %}
{{ product.title }}
{% endfor %}
Or you could be a smarty pants and gather the handles of the products manually yourself. Store them in a metafield resource assigned to the article. For example, a string like 'a-blah,b-blahblah,c-zigo-von-goober' and then use Liquid to find that metafield in the article template. Split that string by commas. Now use the most excellent all_products like this:
{% assign fizzbuzz = all_products['a-blah'] %}
{{ fizzbuzz.title }}
And there are many more creative options. Shopify Liquid is ripe for play like this. No limits, except on all_products at 20... you cannot go more than that.

Targeting a Collection - Liquid

Greetings Shopify Pals!
I have a website at: https://www.blakesseedbased.com/ (password: TopSecretPass)
The Goal:
We will have products that vary in quantity and would like to display this quantity information between the product title and price from the featured home page products (raspberry, chocolate chip, pineapple).
The Issue:
Currently we're able to add content to this area, but we cannot seem to get the if else statement to work correctly. We have a collection called "Snack Bars" however our logic isn't recognising this and injecting the proper code. We tried changing the collection Snack Bars to lower and uppercease snack-bars/Snack-Bars but no luck.
The Logic:
IF the product item is from the Snack Bar collection, add the box quantity (box of 12).
Else, add "no quantity"
The Code:
{% if product.collections contains 'snack-bars' %}
<span>Box of 12</span>
{% else %}
No Box Amount
{% endif %}
Thanks in advance!!
Greetings Birdie Golden!
The issue you're hitting is that product.collections is an array of Collection objects when you're accessing it in Liquid, and no collection object will ever equal a string value.
Luckily, we can easily create an array of handles using the map filter and assign that to a variable, like this:
{% assign collection_list = product.collections | map: 'handle' %}
{% if collection_list contains 'snack-bars' %}
...
The map filter above will create a new array using just the value that you pass it, so the collection_list variable will be an array of just-the-handles. Since handle is a string, we can use contains as expected to see if the value we want is in the list.
Hope that helps!

Shopify - Order Products By Custom Field

we have a simple Shopify store using the free "Meta Fields Editor" to add a simple custom field integer value to each of the products. Some products will have a meta value of 3, others 2 or 1. Many will have no meta value at all. We would like to be able to display the products in search results, by the meta field value entered for each product in descending order (weighted ordering). However, despite the ability to set meta values and display them in search results and collections pages, Shopify does not make it easy to Order or Sort products by a custom meta field. In the search results page I am able to call the custom meta value using
{{item.metafields.important.important}}
So far I have tried to order the products using this method
{% assign products = collection.products | sort:
'item.metafields.important.important' %}
{% for product in products %}
{{ product.title }}
{% endfor %}
But this results in null results.
Any insight anyone can give me in how to display products in order of a custom field would be much appreciated!
After attempting to find a Liquid solution I was finally able to solve this problem using custom metafields and jQuery. In the Shopify collection template, I added a data attribute to be included with each product like so:
<div id="product_list">
<div data-imp="{{product.metafields.important.important}}" class="product_block" /> PRODUCT #1 </div>
<div data-imp="{{product.metafields.important.important}}" class="product_block" /> PRODUCT #2 </div>
</div>
Then I used a simple jQuery function to sort the nodes by data attribute in descending order
var $wrapper = $('#product_list');
$wrapper.find('.product_block').sort(function (a, b) {
return +b.dataset.imp - +a.dataset.imp;
})
.appendTo( $wrapper );
}
Hope this helps somebody!
Nope. Doesn't work. Only fixed filters affect the sorting order. You can manually sort the products from the collection page in admin panel.