I’m trying to set up a page which displays a list of collections, like the general ‘list-collections.liquid’, but only display collections that contain products with a certain product tag.
I’ve tried doing it like this:
{% assign var = 'test' %}
{% assign tagtrue = false %}
{% for collection in collections %}
{% unless collection.handle == 'frontpage' %}
{% for product in collection.products %}
{% for tag in product.tags %}
{% if tag contains var %}
{% assign tagtrue = true %}
{% endif %}
{% endfor %}
{% endfor %}
{% if tagtrue == true %}
<a href="{{ collection.url }}" title="{{ 'collections.general.link_title' | t: title: title }}">
{% if collection.image != blank %}
{{ collection | img_url: '480x480' | img_tag: collection.title }}
{% elsif collection.products.first != blank %}
{{ collection.products.first | img_url: '480x480' | img_tag: collection.title }}
{% else %}
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }}
{% endif %}
</a>
<p>
<a href="{{ collection.url }}" title="{{ 'collections.general.link_title' | t: title: title }}">{{ collection.title }}</a>
</p>
{% endif %}
{% endunless %}
{% endfor %}
But when I go to the collection list page this still returns all collections. Any ideas how to do this?
2
Answers
If you look at the documentation, you’ll find that a product has a special method on it labelled collections. In other words, that gives you a list of all the collections the product belongs to.
So now on to your question. You ask how you can display a list of collections, but only the ones that contain products with a specific tag. OK… fair enough. You will blow speed out the window, but a simple algorithm might be:
Once done that loop, you have the answer. A list of collections for products with a specific tag.
Good luck with performance on that, and remember to keep it simple. That looping is fast for a small shop with limited inventory, but if you have many thousands of skus with a tag spread out across many collections, you’ll be challenged for instant rendering.
You can get a speed improvement over David Lazar’s answer by using Shopify’s
map
filter.As with his answer, step 1 is to create a collection with the rule “Product contains tag” and enter the tag that you are using.
Now assuming that you have that collection object in a Liquid variable named
collection
, you would get the handles of all the collections through a simplemap
command, followed by auniq
command to strip out all the duplicates:The
map
filter gets very specific information from the wad of objects, so it’s quite a bit faster than iterating through a lot of big objects with a slew of fields you don’t care about.(Note that
uniq
only works on strings, numbers, or other simple data types, which is why we map all the way to the collections’ handles)Now you can iterate through
all_collection_handles
to do what you need to do:Since you should have a much shorter list of collections than you do of products, this should be reasonably performant. Be aware as always that the more heavy-lifting that you’re doing in the Liquid code the more likely you’ll get page-load delays, so keeping your loops short and using focused filters such as
map
whenever possible will help keep things running as fast as possible.Note: If your page starts to suffer from extreme page-load lag, you may want to skip doing this as part of the page-load and just leave a placeholder element, then use Javascript to fetch the information you need and create the display you want.