Displaying color variants as individual products on custom collection page

New Member
6 0 0

I'm having some difficulty in creating a shoe store for a client.

FIrst off, they needed a "shop all" page to display all products on a page, but each product needed to be in it's own collection. For example, we have 2 collections currently - Low Tops and Hi Tops. So the first section will show Low Tops, then list every product, then a second section Hi Tops, then display all products in the Hi Tops collection.

I was able to do this, but now they want the ability to show each color variant as an individual product. For example, let's say we have a shoe called Shoe One that comes in two colors 'white' and 'black'. This Shop All page should display the product Shoe One as 2 products, one for the white variant and one for the black variant.

Here's an example of another shopify store that is doing this: https://www.koio.co/collections/collection-men

Here is the original code I wrote to pull in the collections and display them as individual products:

<div class="full-width-desktop-padding" id="Collection">
    <div class="section-header text-center">
      <h2>Shop All Collections</h2>
    </div>
    {% for collection in collections %}
    <div class="collection-wrapper">
      <div class="section-header text-center">
        <h1 class="collection-title">{{ collection.title }}</h1>
      </div>
      <ul class="grid grid--uniform grid--view-items">
        {% for product in collection.products %}
        <li class="grid__item grid__item--collection-template small--one-half medium-up--one-quarter">
          {%- assign max_height = 300 -%}
          {% include 'product-variant-card-grid', max_height: max_height %}
        </li>
        {% endfor %}
      </ul>
      <div class="grid__item medium-up--eight-twelfths medium-up--push-one-sixth"><hr /></div>
      <div class="clearfix"></div>
    </div>
    {% endfor %}
  </div>

I've tried multiple ways of editing that block of code above to run an if/else statement inside to check if a product has more than one of the variant option 'Color': if only one color variant, display product as normal, if more than one color variant, display the product with the color variants as individual products and also display the variant image as the featured image.

This is the latest code I've tried, but after a whole day of attempts, I still can't get this working.

<div class="full-width-desktop-padding" id="Collection">
    <div class="section-header text-center">
      <h2>Shop All Collections</h2>
    </div>
    {% for collection in collections %}
      <div class="collection-wrapper">
        <div class="section-header text-center">
          <h1 class="collection-title">{{ collection.title }}</h1>
        </div>
        <ul class="grid grid--uniform grid--view-items">   
          {% for product in collection.products %}
          	{% capture colour_variant %}
            {% for variant in product.variants %}
            {% for option in variant.options %}
            {% if product.options[forloop.index0] == 'Color' %}somestring,{% endif %}
            {% endfor %}
            {% endfor %}
          {% endcapture %}

          {% assign colour_variant_split = colour_variant | split: 'somestring,' | uniq %}
          {% assign colour_count = colour_variant_split.size | minus:1 %}

          {% if colour_count == 1 %}
              <li class="grid__item grid__item--collection-template small--one-half medium-up--one-quarter">
                {{ colour_count }}
                {%- assign max_height = 300 -%}
                {% include 'product-card-grid', max_height: max_height %}
              </li>	
            {% else %}
              {% for variant in product.variants %} 
                {% assign featured = variant %}
                  <li class="grid__item grid__item--collection-template small--one-half medium-up--one-quarter">
                    {{ colour_count }}
                    {%- assign max_height = 300 -%}
                    {% include 'product-variant-card-grid', max_height: max_height %}
                  </li>
              {% endfor %}
            {% endif %}
          {% endfor %}
        </ul>
        <div class="grid__item medium-up--eight-twelfths medium-up--push-one-sixth"><hr /></div>
        <div class="clearfix"></div>
      </div>
    {% endfor %}
  </div>

If it helps, all products have the first variant option as size, and second variant option as color.

Any help getting this working is greatly appreciated!!

0 Likes
Shopify Partner
2536 31 565

Kevin, I'm usually using code similar to this: https://dylanjh.com/blogs/15-show-all-colors-of-a-product-as-separate-products-on-the-collection-pag...

The idea is to basically for each product loop over variants, get variant color and output this variant if color not in the list of colors for this product (and then add this color to the list), so no color gets output twice.

{% for product in collection.products %}
{% for option in product.options %}
   {% if option == 'Color' %}
   {% assign index = forloop.index0 %}
   {% assign colorlist = '' %}
   {% assign color = '' %}
   {% for variant in product.variants %}
   {% capture color %}
   {{ variant.options[index] }}
   {% endcapture %}

     {% unless colorlist contains color %}
        <-- INSERT PRODUCT LOOP -->
        {% capture tempList %}
      {{colorlist | append: color | append: " " }}
      {% endcapture %}
      {% assign colorlist = tempList %}
      {% endunless %}
      {% endfor %}
    {% endif %}
  {% endfor %}
{% endfor %}

The idea is to basically for each product variant get its color and output this variant if color not in the list of colors for this product (adding this color to the list), so no color gets output twice.

 

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
1 Like
New Member
6 0 0

Wow thanks so much Tim for linking that code!

Got it working perfectly first try!

0 Likes
Shopify Partner
4 0 0

where do I need to add the code? Please!

thank You

0 Likes
New Member
3 0 0

Hi Tim,

 

I am having similar issues, where would I want to paste this code? in collection-list-template.liquid?

 

Thanks for your help!

0 Likes
Shopify Expert
25 0 3

How would this affect collection filtering? It looks like the example site given (koio.co) does it the other way around... create colors as separate products and then brings them together as a swatch on the product page

apollomerchants.com
0 Likes
Highlighted
Shopify Partner
14 0 1

I have done it both ways and I find creating a separate product for each color (like the koio.co site) works better.  Having a separate product for each color is advantageous when filtering by color because the customer sees the image that matches the color they are searching for.  Additionally this approach gets around the 100 variant limitation on a product which comes into play easily with shoes.  If you have 13 sizes per color a single product can only support 7 colors.  If you add an option for width with medium and wide you are down to 3 colors. 

The koio.com implementation is one way of getting all the products on a page, but there are others that do not require a page reload every time a different color is selected.  Regardless of the approach the first step is to group the related color-products together into a collection so that we know what to show together.  You can use tags or other attributes of the product to create the collections. 

Showing them together:

  • Shopify themes convert the product liquid object to JSON in a script to make it accessible to the code javascript code that controls options selection. 

    Look for code like this in the product.template.liquid or product.liquid file:

      <script type="application/json" id="ProductJson-{{ section.id }}">
        {{ product | json }}
      </script>
  • Shopify adds product variants to the cart using the variant_id.
  • Published themes are required to use the OptionSelector callback functionality to implement the option selection.

This means that for most any theme we can add variants to the product JSON and the DOM that the Shopify code uses to display and navigate options without breaking that functionality. 

Start by identifying the collection associated with the product that defines the group.  This code looks for a collection that has a description starting with the word style:

{% for collection in product.collections %}
  	{% assign a = collection.description | downcase | truncate: 5, '' %}
  	{% if a == 'style' %}
  	{% assign product_collection = collection %}
  	{% break %}
  	{% endif %}
{% endfor %}

Next create arrays of variants and images in the group:

{% assign variants = product.variants %}
{% assign images = product.images %}

{% if product_collection %}
  {% for p in product_collection.products %}   
  	{% if p.id != product.id and p.available %}
  		{% assign variants = variants | concat: p.variants %}
	{% endif %}
  {% endfor %}
  {% for p in product_collection.products %}   
  	{% if p.id != product.id and p.available %}
  		{% assign images = images | concat: p.images %}
	{% endif %}
  {% endfor %}
{% endif %}

 

Go through the code in the file and replace loops that use product.variants and product.images with variants and images variables.  

 

Replace {{ product | json }} with code to recreate a product JSON that contains all variants and images:

{"id":{{product.id | json}},"title":{{product.title | json}}, "handle":{{product.handle | json}}, 
  "description":{{product.description | json}}, "published_at":{{product.published_at | json}},
  "created_at":{{product.created_at | json }}, "vendor":{{product.vendor | json}}, "type":{{product.type | json}},
  "tags":{{product.tags | json}}, "price":{{product.price | json}},"price_min":{{product.price_min | json}}, 
  "price_max":{{product.price_max | json}}, "available":{{product.available | json}}, "price_varies":{{product.price_varies | json}},
  "compare_at_price":{{product.compare_at_price | json}},"compare_at_price_min":{{product.compare_at_price_min | json}}, 
  "compare_at_price_max":{{product.compare_at_price_max | json}}, "compare_at_price_varies":{{product.compare_at_price_varies | json}},
  "variants":[ 
          {% for variant in variants %}
{{variant | json}}{% unless forloop.last == true %},{%endunless%}
          {% endfor %}
  ],
  "images":[
          {% for image in images %}
{{image | json}}{% unless forloop.last == true %},{%endunless%}
          {% endfor %}
], "featured_image": {{product.featured_image | json}}, "options":{{product.options | json}},
  "content":{{product.comntent | json}}
}

 

Additional effort is required to show only the images associated with the "color-product" for the selected variant.

 

1 Like
Shopify Expert
25 0 3

Thanks Brian, interested in helping me set this up as a quick job? I'm using the Handy theme by Pixel Union.  If so, I can be reached at info@apollomerchants.com

apollomerchants.com
0 Likes
Tourist
8 0 1

Hi,
 
It's an old thread but probably many merchants are still asking the same question about listing product variants on collection pages. We have recently developed an app which allows to list variants as separate products on collection pages. Here is a link: https://apps.shopify.com/show-variants-on-collection-page . With the app you can automatically show all available variants or select variants to be displayed per collection.
 
Here is a link to our demo store if you would like to see the app in action.

0 Likes
Shopify Expert
25 0 3

Does this work with Filtering? Such as with the app Product Filter & Search

apollomerchants.com
0 Likes