Display product loop based on tag only in Shopify - shopify

I'm trying to display a product loop in a Collection template on Shopify. I want to pull all products with a specific tag 'Hydrate' to display within the Collection.
The template file is collection.custom.liquid and so far I have the below:
{% for product in collection.products %}
{% if product.tags contains "Hydrate" %}
Do Something
{% endif %}
{% endfor %}
But it doesn't display anything. I have confirmed I do have the tags setup correctly and I'm even using the exact same case sensitivity in case thats a thing.
If someone could point me in the right direction to display products from the tag 'Hydrate' in a custom collection template that would be great! Thanks so much
EDIT
I've now altered the code and moved it outside any pagination, and added for each product to the below. It now displays however it keeps displaying the same tags 5 times over on the page. Is there an issue with my syntax? Any ideas?
{% for product in collection.products %}
{% for product in products %}
{% if product.tags contains "Hydrate" %}
<p>{{ product.title }}</p>
{% endif %}
{% endfor %}
{% endfor %}
EDIT 2
In case anyone else has this same issue in future, the below code is what has ended up working and displays the correct tags, the correct amount of times:
{% assign products = collection.products %}
{% for product in products %}
{% if product.tags contains "Hydrate" %}
<p>{{ product.title }}</p>
{% endif %}
{% endfor %}

Your code is correct, so it might be a pagination issue. For example, there are no product with this tag in the first page but there are in the second one.

Related

Exclude product with tag from all collection page liquid

I'm still very new to Shopify so my knowledge of it is very limited.
I've created a page where I want to show certain products with the tag "export". These products should never come up on the collection page (siteurl/collection/all).
I've tried excluding the products with the tag from the collection template but that only leaves gaps on the pages its excluding.
This is my current code:
{% for product in collection.products %}
{% if product.tags contains 'export' %}{% continue %}{% endif %}
My code for displaying the product
{% endfor %}
I've also tried:
{% for product in collection.products %}
{% unless product.tags contains 'export' %}
My code for displaying the product
{% endunless %}
{% endfor %}
My thinking is that I'll need to set the conditions before I call my products so my pagination doesn't break. Is there a way to do this in Shopify?
What you need to know is that Liquid performs the initial action (for product in collection.products) before then performing the next one.
So the forloop grabs all of the products, and then your if statement removes those products. Unfortunately, the pagination has already performed the product split during the forloop, so when you remove the product, it removes it from the paginated result.
There is, annoyingly, no way around this.
The only realistic solution is to create your own all collection and then use smart filters to add everything except products tagged with xyz.
This code should work for you, it is rudimentary and includes some code that could be excluded but will help you understand how it works
CODE FOR YOUR COLLECTION TEMPLATE:
{% for product in collection.products %}
<!-- Set the default value of "product_show" to "true" -->
{% assign product_show = true %}
<!-- We iterate all the tags inside the product checking if one of them EXACTLY matches with "Export" -->
{% for tag in product.tags %}
{% if tag == "export" %}
<!-- If we find an "export" tag then we set product_show to "false" -->
{% assign product_show = false %}
<!-- When we find the label we exit the "FOR" loop -->
{% break %}
{% endif %}
{% endfor %}
<!-- If the product has "product_show" then it will not be shown and will continue with the next product -->
{% if product_show == "true" %}
CODIGO DEL PRODUCTO
{% endif %}
{% endfor %}

Shopify' s all_products[ ] does only accept title

For a client I'm building a way to choose what products are shown in the recommended products section on the product page. To achieve this I thought about inserting the handles from the products I'd like to display into the tag part of the product.
So I'm able to loop over all the tags from the product and then for every tag I'd take the product object and display it. The problem is this code doesn't seem to work:
{% for tag in tags %}
{% for single_product in all_products[tag] %}
{{ single_product }}
{% endfor %}
{% endfor %}
This code does work:
{% for tag in tags %}
{% for single_product in all_products[tag].title %} <---- Added .title
{{ single_product }}
{% endfor %}
{% endfor %}
Sadly, I need the entire product object to display it instead of only the product title. How do I achieve this in shopify?
Side info: This code is placed inside of the framework--product-recommendations.liquid file
The solution was using the collection instead of the all_product. I create a collection containing all product and was perfectly able to loop over it.
My code looks like this now:
{% for tag in tags %}
{% for single_product in all_the_products %}
{% if tag == single_product.handle %}
<div class="product-recommendations--item">
{%
render 'framework--product--item',
product: single_product,
view: 'grid'
%}
</div>
{% endif %}
{% endfor %}
{% endfor %}
all_the_products is assigned to a collection containing all the products.

Shopify check if Metafield exists?

I'm looking to hide content if the metafields are empty for a product, but right now it's returning it for all pages which means my if statement is broken somewhere.
Product Page
{% if product.metafields.review %}
{% include 'extra-review' %}
{% else %}
{% endif %}
Review Snippet Page (extra-review.liquid)
{% assign review = product.metafields.review %}
{% assign key = 'author' %}
{% assign key = 'author-img' %}
{% assign key = 'long' %}
<p> Hello world </p>
Any help would be brilliant
EDIT
Added review metafields layout
To check if a namespace exists you can do a comparison against blank. For example:
{% if product.metafields.review != blank %}
...
{% endif %}
You could also used the size if you wanted to ensure you had three keys. Here we simply output the size:
{{ product.metafields.review.size }}
More info on truthy/falsy can be found in the Shopify docs:
https://help.shopify.com/themes/liquid/basics/true-and-false
Truthiness in Liquid is not like Javascript. I've been bitten by this a few times:
Your test should be:
{% if product.metafields.review == true %}
...
{% endif %}
and review in product.metafields.review is the namespace of the review metafields. see https://help.shopify.com/themes/liquid/objects/metafield

how to limit the numbers of product to show

I'm new to shopify. I'm trying to limit the output of the product for example 4 product for each tag. but seems like there is variables for me to loop..
anyone can help? thx.
{% for tag in collection.all_tags %}
{% if current_tags contains tag %}
<li class="active">{{ tag | link_to_remove_tag: tag }}</li>
{% else %}
<li>{{ tag | link_to_add_tag: tag }}</li>
{{ tag }}
{% if collection.products.size > 0 %}
<ul class="product-grid just">
{% for product in collection.products %}
{% if product.tags contains tag %}
<li>{% include 'product-grid-item' %}</li>
{% endif %}
{% endfor %}
</ul>
{% else %}
<p><strong><br/>No products found in this collection.</strong></p>
{% endif %}
{% endif %}
{% endfor %}
The limit parameter can be used to display the first 4 products in a collection:
{% for product in collection.products limit:4 %}
However if you need to display a limited number of products with a given tag, you will need to implement your own counter. See this discussion on the Shopify forums for an example of how to do this.
E.g.
{% for tag in collection.all_tags %}
{{ tag }}
{% assign counter = 0 %}
{% for product in collection.products %}
{% if product.tags contains tag and counter < 4 %}
<li>{% include 'product-grid-item' %}</li>
{% assign counter = counter | plus: 1 %}
{% endif %}
{% endfor %}
{% endfor %}
For a good separation the logic how many items are to be displayed is better put somewhere the "List" is made ready for output.
This way you don't have to do content related maths in the view, which is never a good idea since it doesn't put code where it belong and other people wanting to change something may have difficulties to find it. That being said you can either put the limitations on the collection.products object based on a configured backend parameter just before handing the object to the rendering or you go further back and intervene at the "grab products from database" point and limit/alter the result. ;)
There sure is a possibility to use an incrementing counter and stop at 4 in the template but I can hardly recommend to use that since it's not where the logic should be. The template should show, not think what to show, otherwise it's hardly reusable.

Shopify If in collection then display this

I am trying to write a simple if statement, but always struggle with shopify's system.
Essentially I want it to do this:
{% if collection.product == 'discontinued' %}
This Product is Discontinued.
{% endif %}
If it's in this collection, then display this text/html. Otherwise it wouldn't display anything. This would be in the product.liquid template.
Any ideas?
This is what ended up working:
{% for c in product.collections %}
{% if c.handle == "discontinued" %}
This product is Discontinued
{% endif %}
{% endfor %}
You can create an array of the collections for a product using map on product.collections. This which will create a new array with your specified property, i.e. the handles of each collection.
You can then check if this new array contains the handle you want to work with.
{% assign productCollections = product.collections | map: "handle" %}
{% if productCollections contains 'your-collection-handle' %}
{% comment %} DoSomething {% endcomment %}
{% endif %}
So for your example:
{% assign productCollections = product.collections | map: "handle" %}
{% if productCollections contains 'discontinued' %}
This product is Discontinued
{% endif %}
You can map other fields if your case is different, such as the title.
I guess this will help any one, I have used in the sidebar of shopify website.
The current collection page will get checked by this below code.
<div class="row-fluid not-animated" data-animate="fadeInUp">
<div class="title">By Collections</div>
<form class="coll">
{% assign col_tags = collection.title %}
{% for collection in collections %}
<input type="radio" value="{{ collection.url }}" name="collections" {% if col_tags contains collection.title %} checked {% endif %} >{{ collection.title | escape }} <br/>
{% endfor %}
</form>
If I understand how liquid collections work in Shopify, you will need to iterate over all of your products.
You'd need to do something similar to this if you are working with collections directly:
{% for product in collection.product %}
{% if product.tags contains 'discontinued' %}
This product has been discontinued :(
{% endif %}
{% endfor %}
If you are just working with a single product you can probably just use the inner if liquid tag part.
References:
Collection.liquid
Product.liquid
You can indeed add discontinued products to a collection called discontinued.
When rendering a product, you could do as csaunders suggests, simply loop through all the products in the discontinued collection, and check if the id of the current product matches any of the products in that collection. If so, do what you must do. No need to use tags.