Collection Filtering on Metafield

Solved
maxwkf
Shopify Partner
3 1 0

Hi there,

 

I would like to do filtering of my collections by metafields in liquid. How should I do it?

 

If I use the where in collection predefined fields, I can do it like this. {% assign collections = collections | where: 'description', 'promotion' %}

 

But while I am trying to do query on the 'group' metafield I have created, it simply not working.

 

{% assign collections = collections | where: 'metafields.custom.group', 'promotion' %}

 

I tried to use this solution (https://community.shopify.com/c/technical-q-a/filtering-collections-by-metafields-using-where/m-p/18...) and surf on the Internet and can get no useful information.

 

Please help Thanks

Accepted Solution (1)
maxwkf
Shopify Partner
3 1 0

This is an accepted solution.

I think the where in liquid won't be able to support a dot operator to retrieve nested array value.

The following is the definition of where in ruby.  Unless array in Ruby support dot operator property value like 'metafields.custom.group', it cannot support for what I mentioned.

# @liquid_public_docs
    # @liquid_type filter
    # @liquid_category array
    # @liquid_summary
    #   Filters an array to include only items with a specific property value.
    # @liquid_description
    #   This requires you to provide both the property name and the associated value.
    # @liquid_syntax array | where: string, string
    # @liquid_return [array[untyped]]
    def where(input, property, target_value = nil)
      ary = InputIterator.new(input, context)

      if ary.empty?
        []
      elsif target_value.nil?
        ary.select do |item|
          item[property]
        rescue TypeError
          raise_property_error(property)
        rescue NoMethodError
          return nil unless item.respond_to?(:[])
          raise
        end
      else
        ary.select do |item|
          item[property] == target_value
        rescue TypeError
          raise_property_error(property)
        rescue NoMethodError
          return nil unless item.respond_to?(:[])
          raise
        end
      end
    end

 

View solution in original post

Replies 3 (3)
NomtechSolution
Excursionist
1020 85 112

To filter collections by metafields in Liquid, you can use the following approach:

  1. Retrieve all collections using the collections object. For example: {% assign collections = collections.all %}.
  2. Loop through the collections and filter them based on the desired metafield value. In this case, the metafields.custom.group metafield is used for filtering.
  3. Use the where filter to compare the metafield value and filter the collections accordingly.

Here's an example of how you can achieve this:

{% assign filteredCollections = collections.all | where: 'metafields.custom.group', 'promotion' %}

{% for collection in filteredCollections %}
  <h2>{{ collection.title }}</h2>
  <!-- Display other collection information here -->
{% endfor %}

In this example, the filteredCollections variable will contain only the collections that have a metafield with the key custom and value promotion in the group subfield.

Need a Shopify developer? Chat on WhatsApp: +923246370042
Hire us at noumanmasood64@gmail.com
For Shopify Design Changes | Shopify Custom Coding | Custom Modifications
maxwkf
Shopify Partner
3 1 0

{{ collections.all }} returns a null

maxwkf
Shopify Partner
3 1 0

This is an accepted solution.

I think the where in liquid won't be able to support a dot operator to retrieve nested array value.

The following is the definition of where in ruby.  Unless array in Ruby support dot operator property value like 'metafields.custom.group', it cannot support for what I mentioned.

# @liquid_public_docs
    # @liquid_type filter
    # @liquid_category array
    # @liquid_summary
    #   Filters an array to include only items with a specific property value.
    # @liquid_description
    #   This requires you to provide both the property name and the associated value.
    # @liquid_syntax array | where: string, string
    # @liquid_return [array[untyped]]
    def where(input, property, target_value = nil)
      ary = InputIterator.new(input, context)

      if ary.empty?
        []
      elsif target_value.nil?
        ary.select do |item|
          item[property]
        rescue TypeError
          raise_property_error(property)
        rescue NoMethodError
          return nil unless item.respond_to?(:[])
          raise
        end
      else
        ary.select do |item|
          item[property] == target_value
        rescue TypeError
          raise_property_error(property)
        rescue NoMethodError
          return nil unless item.respond_to?(:[])
          raise
        end
      end
    end