How does one display a collection list filtered by customer tags in shopify using `assign collection =`

Viewed 1410

I'm trying to create a section within the 'Simple' Shopify theme that filters collections based on customer tags. For example, the customer has the following tags "Foo", "Bar". In turn display the following collections "Foo", "Bar".

I'm not too familiar with liquid so I'm trying to keep things as simple as possible. As such I have duplicated the collection-list.liquid from the 'Simple Theme' for my base and made the following edits to the file.

My Edits

  <!-- the magic -->
  <div class="collection-grid">
    <div class="grid grid--uniform">
      
        {% for tag in customer.tags %} // check customer tags.
      
        {% capture tag_handle %} // capture tag URL handle e.g. /t-shirts in a variable 'tag_handle'
            {{ tag | handle }}
        {% endcapture %}
      
          {% unless collection.handle contains tag_handle %} // check collection handles against the current tag handle to find a match. If so then do.

            <div class="grid__item {{ grid_item_width }} slide-up-animation animated" {{ block.shopify_attributes }} role="listitem">
              {% assign collection = collection.handle %} // Assign correct collection. I suspect this to be my stumbling block. See below for reason why.
              {% include 'collection-grid-item' %}
            </div>

          {% endunless %}
        {% endfor %} 

    </div>
  </div>
  <!-- / the magic -->  

With the current code snippet, I do get results equal to the number of customer tags. The problem is that the results are empty, or at least the assigned collection variable is empty.

Any help with this would be greatly appreciated. Thanks in advance.

2 Answers

If you don't want to have to set up and maintain section blocks, how about something like this?

<!-- the magic -->
<div class="collection-grid">
  <div class="grid grid--uniform">
    
    {% for tag in customer.tags %} // for each customer tag do
      {% assign tag_handle = tag | handle %} // get the tag handle (I.e. no spaces & lowercase)

      {% assign collection = collections[tag_handle] %}
      {% if collection == blank %}
        {% continue %}
      {% endif %}

      <div class="grid__item {{ grid_item_width }} slide-up-animation animated" role="listitem">
        {% include 'collection-grid-item' %}
      </div>


    {% endfor %} 
  </div>
</div>
<!-- / the magic -->

This approach will:

  • Loop through all the customer tags, as before, then
  • Takes the handle-ized version of the tag and performs a collection lookup
  • Skips to the next tag if there was no matching collection found
  • Displays the collection grid item if there is a matching collection

If you are expecting customers to have a lot of tags but only a few collection-related tags, one possible improvement may be to use a special prefix for the collection-related tags that you can check for and skip to the next tag if the prefix is not present. I also know that Shopify has a limit of 50 uses of the all_products lookup per page, but I don't know if there is a similar limit for collection lookups. Either way, for page performance it is probably best if the number of tags and collection lookups is kept reasonably small.


As an aside, one of the things you may be concerned with is page load time. Having too many expensive Liquid operations can cause Shopify's servers to have a bit of delay when serving your site's pages. While you're trying and testing solutions, one extremely useful tool that you can take advantage of is the "Shopify Theme Inspector" plugin for Chrome. This will give you a visual breakdown of how long it takes for Shopify to put your page together on the back-end. (I have no connection with the plugin at all, it's just a useful tool that I have used a few times when evaluating site performance)

So I was able to resolve my issue by taking a slightly different approach based upon @Bilal Akbar question. Seeing as the existing approach worked in the original Simple Theme why try to alter it? Why not allow the admin to load all collections and simply filter the results during the output.

<!-- the magic -->
<div class="collection-grid">
  <div class="grid grid--uniform">
    
    {% for tag in customer.tags %} // for each customer tag do
      {% assign tag_handle = tag | handle %} // get the tag handle (I.e. no spaces & lowercase)

      {% for block in section.blocks limit: section.blocks.size %} // keeping the original loop from the original file.
        {% if block.settings.collection == tag_handle %} // check the collections list within the block to see If it matches the tag handle. if so then do.

          <div class="grid__item {{ grid_item_width }} slide-up-animation animated" {{ block.shopify_attributes }} role="listitem">
            {% assign collection = collections[block.settings.collection] %}
            {% include 'collection-grid-item' %}
          </div>

        {% endif %} 
      {% endfor %} 
    {% endfor %} 
    
  </div>
</div>
<!-- / the magic -->

Again I'm not too savvy with liquid, If anyone has any alternate or maybe even a better way to achieve my desired result. I would be interested in hearing about it. Thanks again.

Related