Need help displaying related products by tag instead of collection - shopify

I have hundreds of products in a collection, I want to group the items in that collection with similar tags
How do i shows all products with matching tags in the related slider ?
Here's what I've tried so far, i managed to group together all related products in the collection:
{% if settings.show_related_product %}
<div id="related_item" class="home-carousel">
{% if collection == null or collection.handle == 'frontpage' or collection.handle == 'all' %}
{% assign found_a_collection = false %}
{% for c in product.collections %}
{% if found_a_collection == false and c.handle != 'frontpage' and c.handle != 'all' and c.all_products_count > 1 %}
{% assign found_a_collection = true %}
{% assign collection = c %}
{% endif %}
{% endfor %}
{% endif %}
{% if collection and collection.products_count > 1 %}
{% if settings.heading_related_product != blank %}
<h4>{{ settings.heading_related_product }}</h4>
{% endif %}
<div class="related-items">
{% assign current_product = product %}
{% assign current_product_found = false %}
{% for product in collection.products limit: settings.related_product_number %}
{% if product.handle == current_product.handle %}
{% assign current_product_found = true %}
{% else %}
{% unless current_product_found == false and forloop.last %}
<div class="related-item">
{% include 'product-item' with collection.handle %}
</div>
{% endunless %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
{% if settings.show_wear_with and settings.wear_with_col != blank%}
<div id="wear_with_item" class="home-carousel">
{% assign wearwithCol = collections[settings.wear_with_col] %}
{% assign wearwithNum = settings.wear_with_number %}
{% if settings.heading_wear_with != blank %}
<h4>{{ settings.heading_wear_with }}</h4>
{% endif %}
<div class="wear-with-items">
{% for product in wearwithCol.products limit: wearwithNum %}
<div class="wear-with-item">
{% include 'product-item' %}
</div>
{% endfor %}
</div>
</div>
{% endif %}

When you need to filter products by tag, the best solution is to use JS, since liquid doesn't have a native way to do so.
So the best way is to target the /collections/all/TAG page and get the products from there with an AJAX request, since they will be filtered by tags on that page.
So something like so:
fetch('/collections/all/SOME_TAG')
.then(r => r.json())
.then(data => /* Do Something With The data */)
If you really really want to use only liquid code than you can do the following "hack":
{% paginate collections.all.products by 9999 %}
{% for _product in collections.all.products %}
{% if _product.tags contains 'SOME_TAG' %}
Do something here
{% endif %}
{% endfor %}
{% endpaginate %}
But I wouldn't recommend the liquid only solution since that will make the server time load increase quite significantly.

Related

Shopify search for related products is not returning similar tagged products

I have a custom module that returns the first 4 related products by tag. It works on ALMOST products except two tags and I can't figure out why. Excluding variants , there are only 108 products site wide. I am displaying the product tag right above the module for you to see as well.
Sample product page with working tag (PowerChairs)
https://www.gallantmedicalsupply.com/collections/power-chairs/products/compass-sport-power-chair
Sample product page with non-working tag (Walkers)
https://www.gallantmedicalsupply.com/products/walk_002
{% assign product = product %}
{% assign current_tags = product.tags %}
{% assign all_products = collections.all.products %}
<div class="container custom-related-product">
<section>
<div>
{% if section.settings.product_recommendations_heading != blank %}
<div class="twelve{% unless settings.borders_enable %} bottompad{% endunless %}">
<h2 class="text-center">{{ section.settings.product_recommendations_heading }}</h2>
{% echo current_tags %}
</div>
{% endif %}
{% assign related_products = 0 %}
<div class="product-loop center">
{% for similar_product in all_products %}
{% if similar_product.handle != product.handle %}
{% for current_product_tag in product.tags %}
{% if similar_product.tags contains current_product_tag %}
{% render 'product.loop', product: similar_product, block_width: 'three' %}
{% assign related_products = related_products | plus: 1 %}
{% break %}
{% endif %}
{% endfor %}
{% if related_products == 4 %}
{% break %}
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
</section>
</div>
Due to the loop limit of 50 products. I filtered the all.products by collection first (excluding all collection and current product) and then iterating to render.
{% if collection == null or collection.handle == 'frontpage' or collection.handle == 'all' %}
{% assign found_a_collection = false %}
{% for c in product.collections %}
{% echo c %}
{% if found_a_collection == false and c.handle != 'frontpage' and c.handle != 'all-products' and c.all_products_count > 1 %}
{% assign found_a_collection = true %}
{% assign collection = c %}
{% endif %}
{% endfor %}
{% endif %}
<div class="container custom-related-product">
<section>
<div>
{% if section.settings.product_recommendations_heading != blank %}
<div class="twelve{% unless settings.borders_enable %} bottompad{% endunless %}">
<h2 class="text-center">{{ section.settings.product_recommendations_heading }}</h2>
</div>
{% endif %}
<div class="product-loop center">
{% for similar_product in collection.products %}
{% if similar_product.handle != product.handle %}
{% render 'product.loop', product: similar_product, block_width: 'three' %}
{% assign related_products = related_products | plus: 1 %}
{% if related_products == 4 %}
{% break %}
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
</section>
</div>

How to exclude sold out products from related products section Shopify?

I'm trying to prevent that sold out products will be shown on related products section in my Shopify store. I tried to use {% if product.available %} in the beginning of the code but without success.
Here is the code of this section -
{% if collection and collection.all_products_count > 1 %}
{% assign col = collection.handle %}
{% else %}
{% assign col = product.collections.last.handle %}
{% endif %}
{% for tag in product.tags %}
{% if tag contains 'meta-related-collection-' %}
{% assign related_collection_handle = tag | remove: 'meta-related-collection-' %}
{% if collections[related_collection_handle].all_products_count > 0 %}
{% assign col = related_collection_handle %}
{% assign collection = collections[col] %}
{% endif %}
{% endif %}
{% endfor %}
{% if col %}
{% if collections[col].all_products_count != 1 or collections[col].products.first.id != product.id %}
{% assign skip_product = product %}
{% assign products = collections[col].products %}
{% unless sidebar %} <div class="container"> {% endunless %}
<div class="related-products__title {% unless section.settings.related_products_style == 'slider' %}{% if sidebar %}twelve columns{% else %}sixteen columns{% endif %}{% endunless %}">
<h4 class="title center">{{ 'products.product.related_items' | t }}</h4>
<div class="feature_divider"></div>
</div>
<div class="clear"></div>
{% unless sidebar %} </div> {% endunless %}
{% if section.settings.related_products_style == 'slider' %}
{% assign limit = section.settings.related_products_limit %}
<div class="related-products related-products--slider js-related-products-slider">
{% if col and collections[col].all_products_count > 0 and product.available %}
{% include 'product-slider', related_products: true %}
{% endif %}
</div>
{% else %}
{% assign limit = section.settings.related_products_limit | plus: 1 %}
{% assign products_per_row = section.settings.products_per %}
{% if col and collections[col].all_products_count > 0 and product.available %}
{% unless sidebar %}<div class="container related-products--grid">{% endunless %}
<div class="{% if sidebar %}twelve{% else %}sixteen{% endif %} columns">
{% include 'product-loop', related_products: true %}
</div>
{% unless sidebar %}</div>{% endunless %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
Hope to get some help, thank you!
Your related collection assignment looks a little bit complicated but should do the trick.
The issue comes with the second part. Once your collection is defined. This kind of code should work:
{% if col %}
<!-- First, memorize your current product handle -->
{% assign current_product_handle = product.handle %}
<!-- Then open the loop to get products inside related collection -->
{% for product in col.products %}
<!-- Filter your results to avoid identic product and out of stock products -->
{% unless product.handle == current_product_handle %}
{% if product.available %}
{{ product.title }} and other things you might want to display about related products.
{% endif %}
{% endunless %}
{% endfor %}
{% endif %}

Show Related Products by Tag (Shopify)

I have a "Related Products" section on my Product page. Right now it shows products that a related by "collection". Is it possible to show related products that have the same Tag?
This is my related-products.liquid code.
Thanks.
{% assign number_of_products = 4 %}
{% assign number_of_products_to_fetch = number_of_products | plus: 1 %}
{% if collection == null or collection.handle == 'frontpage' or collection.handle == 'all' %}
{% assign found_a_collection = false %}
{% for c in product.collections %}
{% if found_a_collection == false and c.handle != 'frontpage' and c.handle != 'all' and c.all_products_count > 1 %}
{% assign found_a_collection = true %}
{% assign collection = c %}
{% endif %}
{% endfor %}
{% endif %}
{% if collection and collection.products_count > 1 %}
<div class="related">
<h1>You Might Also Like</h1>
<div class="products clearfix">
{% assign current_product = product %}
{% assign current_product_found = false %}
{% for product in collection.products limit: number_of_products_to_fetch %}
{% if product.handle == current_product.handle %}
{% assign current_product_found = true %}
{% else %}
{% unless current_product_found == false and forloop.last %}
<li>
<a href="{{ product.url | within: collection }}" class="product__image" title="{{ product.title | escape }}">
<img src="{{ product.featured_image.src | img_url: '350x350' }}" alt="{{ product.featured_image.alt | escape }}">
</a>
</li>
{% endunless %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
Let's change up your for loop that traverses the collection of items, and ignores items that are not tagged.
{% for product in collection.products limit: number_of_products_to_fetch %}
{% if product.handle == current_product.handle %}
{% assign current_product_found = true %}
{% else %}
{% unless current_product_found == false and forloop.last %}
{% if current_product_found.tags contains 'best-tag-ever' %}
<li>
<a href="{{ product.url | within: collection }}" class="product__image" title="{{ product.title | escape }}">
<img src="{{ product.featured_image.src | img_url: '350x350' }}" alt="{{ product.featured_image.alt | escape }}">
</a>
</li>
{% endif %}
{% endunless %}
{% endif %}
{% endfor %}
Note! This will still only traverse through the collection that is provided. That means that the products that will show up need to be a) included in such collection, and b) be tagged with 'best-tag-ever'. If you would like to show products from the entire store instead of said collection, you can swap out that collection for the all collection which has every product in your store.
Check the below code for adding the related products using Tags -
{% assign number_of_related_products_to_show = 2 %}
{% assign current_product = product %} {% assign current_product_tags = product.tags %}
{% assign found_first_match = false %} {% assign found_second_match = false %}
{% assign first_related_product = true %}
{% paginate collections.all.products by 1000 %}
{% for product in collections.all.products %}
{% unless product.handle == current_product.handle %}
{% for tag in product.tags %}
{% if current_product_tags contains tag %}
{% if found_first_match == false %}
{% assign found_first_match = true %}
{% assign first_match = tag %}
{% else %}
{% assign found_second_match = true %}
{% assign second_match = tag %}
{% endif %}
{% endif %}
{% endfor %}
{% if found_first_match == true %}
{% if first_related_product == true %}
{% assign first_related_product = false %}
Related products
{% endif %}
{% if product.tags contains first_match or product.tags contains second_match %}
{% include 'product-grid-item' with collection.handle %}
{% endif %}
{% endif %}
{% endunless %}
{% endfor %}
{% if first_related_product == false %}
{% endif %}
{% endpaginate %}

Load a Specific Collection as a Shpoify Related Products

I want to load product accessories when an end user looks at a one of my product pages. I have figured out how to exclude collections from displaying,
but I am unsure how to set the 'liquid' to call one collection specifically.
{% assign number_of_related_products_to_show = 12 %}
{% assign number_of_related_products_to_fetch = number_of_related_products_to_show | plus: 1 %}
{% assign exclusions = 'frontpage,all,dual_camera,single_camera,series_dr650s,series_dr400_series' | split: ',' %}
{% if collection == null or collection.handle == 'frontpage' or collection.handle == 'all' %}
{% assign found_a_collection = false %}
{% for c in product.collections %}
{% if collection and collection.all_products_count > 1 %}
{% unless exclusions contains collection.handle %}
{% assign found_a_collection = true %}
{% assign collection = c %}
{% endunless %}
{% endif %}
{% endfor %}
{% endif %}
{% if collection and collection.products_count > 1 %}
<div class="h_row_4 animated fadeInUp" data-animation="fadeInUp">
<div class="clearfix">
<h3>{{ 'products.general.related_products' | t }}</h3>
{% assign current_product = product %}
{% assign current_product_found = false %}
</div>
<div class="carosel product_c">
<div class="row">
<div id="featured-products-section-{{ section.id }}" class="owl-carousel">
{% for product in collection.products limit: number_of_related_products_to_fetch %}
{% if product.handle == current_product.handle %}
{% assign current_product_found = true %}
{% else %}
{% unless current_product_found == false and forloop.last %}
{% include 'product-loop' %}
{% endunless %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endif %}
Any help would be appreciated.
To loop through a specific collection:
{% for product in collections[handle-of-the-collection-you-want].products %}
Do something
{% endfor %}

Shopify - How to exclude a collection in paginate?

I need to exclude a collection inside the paginate loop. But if I use the conditional statement, it will still be counted in paginate count.
So If I paginate by 10 and there are 2 products from the excluded collection in first page, I will only see 8 products in first page.
Any solution for this? Here's my snippet:
{% paginate collection.products by 10 %}
<ul>
{% for product in collection.products %}
<!-- Check for collection -->
{% assign is_treatment = false %}
{% for c in product.collections %}
{% if c.handle == "salon-treatment" %}
{% assign is_treatment = true %}
{% endif %}
{% endfor %}
{% unless is_treatment %}
<li>{{ product.title }}</li>
{% endunless %}
{% endfor %}
</ul>
{% endpaginate %}
Note: This question is duplicated from the one I posted in Shopify forum.
What I did for something like this was first load in all the desired products into a collection of my own (basically an array of objects), and then paginate THAT array... so, if you write a function called exclude_some_products which returns all the unexcluded products, do this:
{% assign my_smaller_collection = exclude_some_products collection %}
{% paginate my_smaller_collection.products by 10 %}
<ul>
{% for product in my_smaller_collection.products %}
<!-- Check for collection -->
{% assign is_treatment = false %}
{% for c in product.collections %}
{% if c.handle == "salon-treatment" %}
{% assign is_treatment = true %}
{% endif %}
{% endfor %}
{% unless is_treatment %}
<li>{{ product.title }}</li>
{% endunless %}
{% endfor %}
</ul>
{% endpaginate %}
p.s. pardon my code, I'm not even sure what language this is!