skip to Main Content

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


  1. 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:

    • create a collection of products with tag foomanchu
    • iterate the products in that collection, and use the product.collections
    • for each collection listed, add it to a list if it has not already been added

    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.

    Login or Signup to reply.
  2. 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 simple map command, followed by a uniq command to strip out all the duplicates:

    {% assign all_collection_handles = collection.products | map: 'collections' | map: 'handle | uniq %}
    

    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:

    {% for handle in all_collection_handles %}
      {% assign collection = collections[handle] %}
      <!-- Cool stuff here -->
    {% endfor %}
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search