Show all product variants in the collections page [DAWN THEME 2.5.0]

Hi all, I’m trying to show all product variations on the collection page, I found some solutions for older themes but I would like to have this feature on the new Dawn theme.

Thanks in advance.

1 Like

Would love it as well!

Hi!

Big shout out to DYLAN HUNT https://dylanjh.com/blogs/15-show-all-colors-of-a-product-as-separate-products-on-the-collection-page. With his help I figured it out for DAWN theme.

Replace the code in the file main-collection-product-grid.liquid (my theme is on swe so change “Färg” to “Color” or other if you use another language

{{ 'template-collection.css' | asset_url | stylesheet_tag }}
{{ 'component-loading-overlay.css' | asset_url | stylesheet_tag }}
{{ 'component-card.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}
{{ 'component-product-grid.css' | asset_url | stylesheet_tag }}

{%- if section.settings.enable_filtering or section.settings.enable_sorting -%}
  {{ 'component-facets.css' | asset_url | stylesheet_tag }}
  

  

    {% render 'facets', results: collection, enable_filtering: section.settings.enable_filtering, enable_sorting: section.settings.enable_sorting, collapse_on_larger_devices: section.settings.collapse_on_larger_devices %}
  

{%- endif -%}

  {%- paginate collection.products by section.settings.products_per_page -%}
    
      

        

        
          
          {%- for product in collection.products -%}
          
            {% assign color_active = false %}
            {% for option in product.options %}
              {% if option == 'Färg' %}
                 {% assign color_active = true %}
              {% endif %}
            {% endfor %}
            {% if product.variants.size > 1 and color_active == true %}
            {% for option in product.options %}
               {% if option == 'Färg' %}
               {% assign index = forloop.index0 %}
               {% assign colorlist = '' %}
               {% assign color = '' %}
               {% for variant in product.variants %}
               {% capture color %}
               {{ variant.options[index] }}
               {% endcapture %}

               {% unless colorlist contains color %}
            - {% render 'product-card-variant',
                  product_card_product: product,
                	variant: variant,
                  media_size: section.settings.image_ratio,
                  show_secondary_image: section.settings.show_secondary_image,
                  add_image_padding: section.settings.add_image_padding,
                  show_vendor: section.settings.show_vendor,
                  show_image_outline: section.settings.show_image_outline,
                  show_rating: section.settings.show_rating, product_options: variant
                %}
            

          {% capture tempList %}
          {{colorlist | append: color | append: " " }}
          {% endcapture %}
          {% assign colorlist = tempList %}
          {% endunless %}
          {% endfor %}
        {% endif %}
      {% endfor %}
            {% else %}
          - {% render 'product-card',
                  product_card_product: product,
                  media_size: section.settings.image_ratio,
                  show_secondary_image: section.settings.show_secondary_image,
                  add_image_padding: section.settings.add_image_padding,
                  show_vendor: section.settings.show_vendor,
                  show_image_outline: section.settings.show_image_outline,
                  show_rating: section.settings.show_rating
                %}
            
            {% endif %}
       {%- endfor -%}
        

        {%- if paginate.pages > 1 -%}
          {% render 'pagination', paginate: paginate, anchor: '' %}
        {%- endif -%}
      

 
  {%- endpaginate -%}

{% schema %}
{
  "name": "t:sections.main-collection-product-grid.name",
  "class": "spaced-section collection-grid-section",
  "settings": [
    {
      "type": "range",
      "id": "products_per_page",
      "min": 8,
      "max": 24,
      "step": 4,
      "default": 16,
      "label": "t:sections.main-collection-product-grid.settings.products_per_page.label"
    },
    {
      "type": "header",
      "content": "t:sections.main-collection-product-grid.settings.header__3.content"
    },
    {
      "type": "select",
      "id": "image_ratio",
      "options": [
        {
          "value": "adapt",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__1.label"
        },
        {
          "value": "portrait",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__2.label"
        },
        {
          "value": "square",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__3.label"
        }
      ],
      "default": "adapt",
      "label": "t:sections.main-collection-product-grid.settings.image_ratio.label"
    },
    {
      "type": "checkbox",
      "id": "show_secondary_image",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_secondary_image.label"
    },
    {
      "type": "checkbox",
      "id": "add_image_padding",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.add_image_padding.label"
    },
    {
      "type": "checkbox",
      "id": "show_image_outline",
      "default": true,
      "label": "t:sections.main-collection-product-grid.settings.show_image_outline.label"
    },
    {
      "type": "checkbox",
      "id": "show_vendor",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_vendor.label"
    },
    {
      "type": "checkbox",
      "id": "show_rating",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_rating.label",
      "info": "t:sections.main-collection-product-grid.settings.show_rating.info"
    },
    {
      "type": "header",
      "content": "t:sections.main-collection-product-grid.settings.header__1.content"
    },
    {
      "type": "checkbox",
      "id": "enable_filtering",
      "default": true,
      "label": "t:sections.main-collection-product-grid.settings.enable_filtering.label",
      "info": "t:sections.main-collection-product-grid.settings.enable_filtering.info"
    },
    {
      "type": "checkbox",
      "id": "enable_sorting",
      "default": true,
      "label": "t:sections.main-collection-product-grid.settings.enable_sorting.label"
    },
    {
      "type": "checkbox",
      "id": "collapse_on_larger_devices",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.collapse_on_larger_devices.label"
    }
  ]
}
{% endschema %}

Make a new file under snippets product-card-variant.liquid and add following code

{% comment %}
    Renders a product card

    Accepts:
    - product_card_product: {Object} Product Liquid object (optional)
	- variant: {String} variant
    - media_size: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional)
    - show_secondary_image: {Boolean} Show the secondary image on hover. Default: false (optional)
    - add_image_padding: {Boolean} Enables padding on the image to space out the grid
    - show_vendor: {Boolean} Show the product vendor. Default: false
    - show_image_outline: {Boolean} Show card outline. Default: true (optional)
    - show_rating: {Boolean} Show the product rating. Default: false
	- variant:  {Object} Show the product variant. Default: true

    Usage:
    {% render 'product-card-variant', show_vendor: section.settings.show_vendor %}
{% endcomment %}

{{ 'component-rating.css' | asset_url | stylesheet_tag }}

  

    

      {%- if show_vendor -%}
        {{ 'accessibility.vendor' | t }}
        
{{ product_card_product.vendor }}

      {%- endif -%}

      {%- if product_card_product.featured_media -%}
        ### 
          
            {{ product_card_product.title | escape }} - {{ variant.title }}
          
        
      {%- endif -%}

      {% comment %} TODO: metafield {% endcomment %}
      {{ block.settings.description | escape }}
      {%- if show_rating and product_card_product.metafields.reviews.rating.value != blank -%}
        {% liquid
          assign rating_decimal = 0 
          assign decimal = product_card_product.metafields.reviews.rating.value.rating | modulo: 1 
          if decimal >= 0.3 and decimal <= 0.7
            assign rating_decimal = 0.5
          elsif decimal > 0.7
            assign rating_decimal = 1
          endif 
        %}
        

          
        

        

          {{ product_card_product.metafields.reviews.rating.value }} / {{ product_card_product.metafields.reviews.rating.value.scale_max }}
        

        

          ({{ product_card_product.metafields.reviews.rating_count }})
          {{ product_card_product.metafields.reviews.rating_count }} {{ "accessibility.total_reviews" | t }}
        

      {%- endif -%}
      {% render 'price', product: variant, price_class: '' %}
    

  

  
    

      {%- if product_card_product.featured_media -%}
        {%- liquid
          assign featured_media_aspect_ratio = product_card_product.featured_media.aspect_ratio

          if product_card_product.featured_media.aspect_ratio == nil
            assign featured_media_aspect_ratio = 1
          endif
        -%}

        

      {%- else -%}
        
          ## 
            
              {{ product_card_product.title }} 
            
          
        

      {%- endif -%}

      
        {%- if product_card_product.available == false -%}
          {{ 'products.product.sold_out' | t }}
        {%- elsif product_card_product.compare_at_price > product_card_product.price and product_card_product.available -%}
          {{ 'products.product.on_sale' | t }}
        {%- endif -%}
      

    

  

2 Likes

Thank you for that snippet @Elinns ! :slightly_smiling_face: Is it possible that there is a bit of code missing? Product pictures are overlaying and Im looking for some unclosed div or sth similar within your product-card-variant atm.

1 Like

Hey, I made some modifications to it to make it work with the current dawn theme. The code posted above has some outdated names and format for the current default snippets.

I am currently on the latest version of Craft theme, but it is just a variation of the Dawn theme so it will still work (unless the snippet names are different then you would just have to change every instance of “card-product” to whatever the default snippet name is).

I took the existing card-product.liquid snippet that is with the theme by default and slightly modified it to make it work with variants. I made this new snippet called card-product-variant.liquid.

This is my code in main-collection-product-grid.liquid

{{ 'template-collection.css' | asset_url | stylesheet_tag }}
{{ 'component-loading-overlay.css' | asset_url | stylesheet_tag }}
{{ 'component-card.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}

{%- style -%}
  .section-{{ section.id }}-padding {
    padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px;
    padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px;
  }

  @media screen and (min-width: 750px) {
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top }}px;
      padding-bottom: {{ section.settings.padding_bottom }}px;
    }
  }
{%- endstyle -%}

  {%- if section.settings.enable_filtering or section.settings.enable_sorting -%}
    {{ 'component-facets.css' | asset_url | stylesheet_tag }}
    
  
    

      {% render 'facets', results: collection, enable_filtering: section.settings.enable_filtering, enable_sorting: section.settings.enable_sorting, collapse_on_larger_devices: section.settings.collapse_on_larger_devices %}
    

  {%- endif -%}
  
  
    {%- paginate collection.products by section.settings.products_per_page -%}
      {%- if collection.products.size == 0 -%}
        

          

          
            ## 
              {{ 'sections.collection_template.empty' | t }}

              {{ 'sections.collection_template.use_fewer_filters_html' | t: link: collection.url, class: "underlined-link link" }}
            
          

        

      {%- else -%}
        
          

  
          
            {%- for product in collection.products -%}
              {% assign lazy_load = false %}
              {%- if forloop.index > 2 -%}
                {%- assign lazy_load = true -%}
              {%- endif -%}
            {% assign color_active = false %}
            {% for option in product.options %}
              {% if option == 'Color' %}
                 {% assign color_active = true %}
              {% endif %}
            {% endfor %}
            {% if product.variants.size > 1 and color_active == true %}
            {% 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 %}
                    
                      - {% render 'card-product-variant',
                            card_product: product,
                            variant: variant,
                            media_aspect_ratio: section.settings.image_ratio,
                            show_secondary_image: section.settings.show_secondary_image,
                            show_vendor: section.settings.show_vendor,
                            show_rating: section.settings.show_rating, variant
                            lazy_load: lazy_load
                          %}
                      

                    {% capture tempList %}
                  {{colorlist | append: color | append: " " }}
                  {% endcapture %}
                  {% assign colorlist = tempList %}
                  {% endunless %}
                  {% endfor %}
                {% endif %}
              {% endfor %}
              {% else %}
              
                - {% render 'card-product',
                    card_product: product,
                    media_aspect_ratio: section.settings.image_ratio,
                    show_secondary_image: section.settings.show_secondary_image,
                    show_vendor: section.settings.show_vendor,
                    show_rating: section.settings.show_rating,
                    lazy_load: lazy_load
                  %}
              
              {% endif %}
            {%- endfor -%}

          

  
          {%- if paginate.pages > 1 -%}
            {% render 'pagination', paginate: paginate, anchor: '' %}
          {%- endif -%}
        

      {%- endif -%}
    {%- endpaginate -%}
  

{% schema %}
{
  "name": "t:sections.main-collection-product-grid.name",
  "class": "section",
  "settings": [
    {
      "type": "range",
      "id": "products_per_page",
      "min": 8,
      "max": 24,
      "step": 4,
      "default": 16,
      "label": "t:sections.main-collection-product-grid.settings.products_per_page.label"
    },
    {
      "type": "header",
      "content": "t:sections.main-collection-product-grid.settings.header__3.content"
    },
    {
      "type": "select",
      "id": "image_ratio",
      "options": [
        {
          "value": "adapt",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__1.label"
        },
        {
          "value": "portrait",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__2.label"
        },
        {
          "value": "square",
          "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__3.label"
        }
      ],
      "default": "adapt",
      "label": "t:sections.main-collection-product-grid.settings.image_ratio.label"
    },
    {
      "type": "checkbox",
      "id": "show_secondary_image",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_secondary_image.label"
    },
    {
      "type": "checkbox",
      "id": "show_vendor",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_vendor.label"
    },
    {
      "type": "checkbox",
      "id": "show_rating",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.show_rating.label",
      "info": "t:sections.main-collection-product-grid.settings.show_rating.info"
    },
    {
      "type": "header",
      "content": "t:sections.main-collection-product-grid.settings.header__1.content"
    },
    {
      "type": "checkbox",
      "id": "enable_filtering",
      "default": true,
      "label": "t:sections.main-collection-product-grid.settings.enable_filtering.label",
      "info": "t:sections.main-collection-product-grid.settings.enable_filtering.info"
    },
    {
      "type": "checkbox",
      "id": "enable_sorting",
      "default": true,
      "label": "t:sections.main-collection-product-grid.settings.enable_sorting.label"
    },
    {
      "type": "checkbox",
      "id": "collapse_on_larger_devices",
      "default": false,
      "label": "t:sections.main-collection-product-grid.settings.collapse_on_larger_devices.label"
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 36
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 36
    }
  ]
}
{% endschema %}

And this is my code for card-product-variant.liquid

{% comment %}
    Renders a product card

    Accepts:
    - card_product: {Object} Product Liquid object (optional)
	- variant: {String} variant
    - media_aspect_ratio: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional)
    - show_secondary_image: {Boolean} Show the secondary image on hover. Default: false (optional)
    - show_vendor: {Boolean} Show the product vendor. Default: false
    - show_rating: {Boolean} Show the product rating. Default: false
    - extend_height: {Boolean} Card height extends to available container space. Default: true (optional)
    - lazy_load: {Boolean} Image should be lazy loaded. Default: true (optional)

    Usage:
    {% render 'card-product-variant', show_vendor: section.settings.show_vendor %}
{% endcomment %}

{{ 'component-rating.css' | asset_url | stylesheet_tag }}

{%- if variant and variant != empty -%}
  {%- liquid
    assign ratio = 1
    if variant.featured_media and media_aspect_ratio == 'portrait'
      assign ratio = 0.8
    elsif variant.featured_media and media_aspect_ratio == 'adapt'
      assign ratio = variant.featured_media.aspect_ratio
    endif
    if ratio == 0 or ratio == nil
      assign ratio = 1
    endif
  -%}
  
    

      

        {%- if variant.featured_media -%}
          

            

              

              {%- if card_product.media[1] != nil and show_secondary_image -%}
                
              {%- endif -%}
            

          

        {%- endif -%}
        
          

            ### 
              
                {{ card_product.title | escape }}
              
            
          

          
            {%- if card_product.available == false -%}
              {{ 'products.product.sold_out' | t }}
            {%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
              {{ 'products.product.on_sale' | t }}
            {%- endif -%}
          

        

      

      
        

          ### 
            
              {{ card_product.title | escape }}
            
          
          
            {%- if show_vendor -%}
              {{ 'accessibility.vendor' | t }}
              
{{ card_product.vendor }}

            {%- endif -%}

            {{ block.settings.description | escape }}

            {%- if show_rating and card_product.metafields.reviews.rating.value != blank -%}
              {% liquid
                assign rating_decimal = 0
                assign decimal = card_product.metafields.reviews.rating.value.rating | modulo: 1
                if decimal >= 0.3 and decimal <= 0.7
                  assign rating_decimal = 0.5
                elsif decimal > 0.7
                  assign rating_decimal = 1
                endif
              %}
              

                
              

              

                {{ card_product.metafields.reviews.rating.value }} / {{ card_product.metafields.reviews.rating.value.scale_max }}
              

              

                ({{ card_product.metafields.reviews.rating_count }})
                {{ card_product.metafields.reviews.rating_count }} {{ "accessibility.total_reviews" | t }}
              

            {%- endif -%}

            {% render 'price', product: variant, price_class: '' %}
          

        

        
          {%- if card_product.available == false -%}
            {{ 'products.product.sold_out' | t }}
          {%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
            {{ 'products.product.on_sale' | t }}
          {%- endif -%}
        

      

    

  

{%- else -%}
  
    

      

        

          

            ### 
              
                {{ 'onboarding.product_title' | t }}
              
            
          

        

      

      
        

          ### 
            
              {{ 'onboarding.product_title' | t }}
            
          
          
            {%- if show_vendor -%}
              {{ 'accessibility.vendor' | t }}
              
{{ 'products.product.vendor' | t }}

            {%- endif -%}
            {% render 'price' %}
          

        

      

    

  

{%- endif -%}

The only issue with this solution is that you can’t use the hover for secondary image option, as currently Shopify only lets you set one image per variant in the product settings. I will look into this more and maybe I can find a solution, but for now this works (at least for my use case).

5 Likes

Awesome, thank you @djeler !

1 Like

Hi @djeler
Thanks a lot for sharing this.

Been looking for a solution for Dawn for a while.

I am however a complete rookie in modifying code so I was hoping you could help me dumb it down a little.

How did you “slightly modify” card-product.liquid?

Thanks.

Peter

Nothing has changed for me

Hello, I have copied the 1st code to main-collection-product-grid.liquid, created the snippet card-product-variant.liquid, but I cannot put the code into it.

Not working for me :disappointed_face:

Here’s a handy video that shows you how to get all product variants and prices up on your Shopify collection pages.

You can do it. It is possible:

This is an excellent answer and provided what I needed to get this done in the theme I’m using. Great job and thanks for sharing.