tagsshopifyliquidcustom-lists

Shopify - How can I match the display order of tags to product display order in a collection?


Hoping some one can help out with this one as I'm still fairly new-ish to working with Shopify's liquid code format.

Recently I have implemented multiple dropdown sorting boxes on collection pages for product filters using tags. Based on this "How-To": https://community.shopify.com/c/Shopify-Design/How-to-Multiple-Dropdown-Sorting-Boxes-on-Collection-...

All this is working as intended, however I am having trouble ordering the tags of one of the filters. I want the display order of the tags to match the current order of the products in the collection (which have been ordered manually from the backend) - see image

Screenshot of the collection page and filters

The code handling this specific dropdown:

<div class="four-columns">
    Package size:
    <select class="coll-filter" id="sizeFilter">
      <option class="size-all" value="">All</option>
      {% for tag in collection.all_tags %}
        {% if tag contains 'size-' %}
         {% assign tagName = tag | remove: 'size-' %}         
          {% if current_tags contains tag %}
          <option class="{{tag}}" value="{{ tag | handle }}" selected>{{ tagName }}</option>
          {% else %}
          <option class="{{tag}}" value="{{ tag | handle }}">{{ tagName }}</option>
          {% endif %}                     
        {% endif %}
      {% endfor %}
    </select>
  </div>  

My main drawback is that I can't "hardcode" the list as there are multiple collections with different package sizes. Any and all help is greatly appreciated. Thanks.


Solution

  • Well if you want to be based on the order of the products, then you will need to use the products instead of grabbing all the tags.

    So it will become something like this:

    {% assign all_tags = '' %}
    {% for product in collection.products %}
      {% for tag in product.tags %}
        {% if tag contains 'size-' %}
          {% assign all_tags = all_tags | append: tag | append: ',' %}
        {% endif %}
      {% endfor %}
    {% endfor %}
    {% assign all_tags_unique = all_tags | split: ',' | uniq %}
    
    <select>
      {% for tag in all_tags_unique %}
        {% assign tagName = tag | remove: 'size-' %}         
        {% if current_tags contains tag %}
          <option class="{{tag}}" value="{{ tag | handle }}" selected>{{ tagName }}</option>
        {% else %}
        <option class="{{tag}}" value="{{ tag | handle }}">{{ tagName }}</option>
        {% endif %} 
      {% endfor %}
    </select>
    

    Where we will loop the current products and push each of their tags to the varaible {% assign all_tags = '' %}.

    After we finish with the products we will split it by our divider, which in our case is , and will add the unique filter which will remove any repeats in the array (in case you have more than one size on a product or a repeat).

    And finally you will loop the newly created tag array all_tags_unique .

    That's all.

    PS: Have in mind that you have more than 50 products you will need to increase the pagination to get them all.


    Have in mind that this is not tested code so there may be a mistake or two but the logic is there. :)