Shopify products' collection empty in collection context - shopify

I'm trying to filter my related products by collections.
Every product belongs to two collections: One for the material, one for the room.
The Material one is an automatic collection which get products with a certain tag.
The Room one is populated manually.
When I get to the product page I load the related products like this (the related product must share both collections with the current product) :
{% for related_product in collection.products %}
{% if product.collections[0].handle ==
related_product.collections[0].handle and product.collections[1].handle
== related_product.collections[1].handle and related_product.handle !=
product.handle %}
<div class="Carousel__Cell">
{% include 'product-item', product: related_product,
show_product_info:
section.settings.show_product_info, show_labels: true %}
</div>
{% endif %}
{% endfor %}
Strangely this work only for some products. In some of them product.collection seems null, which makes no sense!
All of the products appear properly in the correct collection.
The problem is happening in the context of a collection (but we will need to make it work in all contexts)

We found out it was an import/sync problem. We had to remove all existing products and re-import them. It fixed the issue.

Related

Pulling Products From Multiple Collections - Shopify Liquid

I am having trouble trying to pull products from more than one collections that are associated with the product on its product page. I have coded the following:
{% for product in product.collections limit: 6 %}
** Products **
{% endfor %}
However, this just pulls all the list of collections that's associated with the product rather than the products in those collections. I have then tried the following:
{% for product in collections[product.collections].products limit: 6 %}
** Products **
{% endfor %}
Which came back with an "Liquid error: Expected handle to be a String but got Array" error message.
I am not sure how I should approach this. Does anybody know where I've gone wrong?
You are going to fast. Collections is an array so you must first define which collection you need before its products.
So, for example if you want only products from first collection of current product you might try this to access the collection itself inside product.collections array:
{% for product in product.collections.first.products %}
Do something with product object.
{% endfor %}
Then, regarding what you are trying to achieve, first loop through product.collections, then loop through each collection products. Like this:
{% for collection in product.collections %}
{% for product in collection.products limit:6 %}
Do something
{% endfor %}
{% endfor %}
Please note that double loops are greedy and might affect page load time. So you might need to limit primary loop too to avoid unnecessary load if product belongs to lot of collections.

How can I display specific Collection on a product or list page

I have a shopify store with new, used and refurbished amplifiers & speakers.
This condition is stored in a manual collection (four of them). The others collections being automated.
I would like to display the condition of the product on the product page or the products list.
So basically I need to get all the collections and filter to display one of the four :
If the product belongs to collection "used" display collection "used"
If the product belongs to collection "new" display collection "new"
etc...
The closest to what I want to do has been made trough this code :
{% assign product_collection = product.collections.first %}
{% if product_collection %}
This product is part of my {{ product_collection.title | link_to: product_collection.url }} Collection
{% endif %}
Found here : https://community.shopify.com/c/Shopify-Design/RESOLVED-Display-Collection-on-Product-Page/td-p/230899
With this I am not able to filter on the four collections.
I have spent the day on this...If somebody can help, that would save my day :)
You can add all collections(title or handle value) on the product-grid-item.liquid.
<div class= "grid-item
{% for product_collection in product.collections %}
{{product_collection.title | handle }}
{% endfor %}
">
...
</div>
And then you can filter them with JavaScript on the frontend.
Hope this could help you

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.

How to combine for and where clause in Liquid

I'm currently working on a shopify site and need to create a filter on a products page. My goal is to have primer paints show up in a different section of the product collection page. What I'm having trouble with is how to filter for primers. We have a tag set up in the product page named "Primer". What I want is for the loop to check whether a product has the primer tag, and if so, display that as one of the products in the loop. I'm relatively new to Liquid, so I don't know how to combine clauses if that's possible. I've looked up the "Where" clause, but don't entirely understand how it works.
Here is the code as it stands:
<div class="{% if settings.show_collection_sidebar %}desktop-10{% else
%}desktop-12{% endif %} tablet-6 mobile-3" id="bside">
<div id="product-loop">
{% for product in collection.products %}
<div class="product {% if settings.products_per_row == '3' %}
desktop-4{% cycle ' first', '', ' last' %}
{% elsif settings.products_per_row == '4' %}
desktop-3{% cycle ' first', '', '', ' last' %}
{% endif %} tablet-half mobile-half"
id="prod-{{ product.id }}"
data-alpha="{{ product.title }}"
data-price="{{ product.price }}">
{% include 'product-listing' %}
</div>
{% endfor %}
</div>
</div>
How could I filter for the desired results? I've tried {% if product.tags contains 'Primer' %} in quite a few places, but to no avail.
Thanks for your help.
Have you considered using two collections to accomplish what you're after?
If you made a dynamic ("Smart") collection for all your primers (Let's assume the handle for the collection is 'primer'), you can access that collection at any time through Liquid:
{% assign primer_collection = collections['primer'] %}
{% for product in primer_collection.products %}
<h2>HAVE SOME {{ product.title }}!</h2>
{% endfor %}
Then, if you wanted to exclude all of your primer products from the main collection, create a collection named 'all' (or at least with the handle 'all' - the actual title doesn't strictly matter - see footnote). By default, the 'All' collection is, true to its name, every product in your store. However, if you create your own 'all' collection, you can define it to mean "Everything except certain items" - in your case, 'everything but the primer'
Having Shopify pre-filter everything for you through the collections themselves greatly reduces the headaches of trying to apply filters after-the-fact and dealing with misleading item counts, uneven pagination, etc.
Handles: At the bottom of each collection and product in your Shopify admin is the SEO settings. Editing these allows you to change what the handle for the collection/product is, and this is what Shopify uses to look up your collection/product internally

Multiple linklists on shopify categories (sidebar)

Yet another shopify question. I have a sidebar on shop/collections page
settings.sidebar_categoryblock_linklist
Which shows links to my main collecions: men/woman/kinds ect.
Yet I have another collection list based on product tags:
Winter/Autumn/Casual/Business etc
How do I get to display them on the sidebar? Meaning how can I put several linklists as categories link lists?
Thanks in advance
Julia
In a collection page, you have access to all the tags (unique) that the products have. You can use these tags to see if the belong to any collection and then display them. The code is as follows:
{% for tag in collection.all_tags %}
{% assign c_collection = collections[tag] %} // c_collection is used so the current display page's collection doesn't get disturbed
{% if c_collection.title != '' %}
{{ tag | link_to: c_collection.url,c_collection.title }} // not sure about this, but you can use proper html as well here
{% endif %}
{% endfor %}