Re: Product Reference Shopify Metafields

Solved

How can I properly display products using Shopify Metafields?

michaelmorgan
Shopify Partner
32 2 5

My client is wanting to move from Accentuate Custom Fields to Shopify Metafields and I am running into an issue with one feature. Basically I need to display a list of products with their image, title, and price in a column. I have added a product_list schema setting for the section and connected it to the Shopify product reference metafield, but for some reason, it is displaying the product itself instead of the products listed in the metafield. Below is the code I have so far.

<div class="feature-row">
      {%- if section.settings.layout == 'left' -%}
        {{ image_layout }}
      {%- endif -%}
      {% assign handle = section.settings.featured_products | metafield_tag %}
      {% assign handles = handle | split:'|' %}
      {% assign product_handle = handle %}

      <div class="product-style-half">
        <div class="product-style__product-grid">
        {% if handles.size > 0 %}
        {% for product_handle in handles %}
          {% assign product_title = all_products[product_handle].title | capitalize %}
            <div class="grid-product__content feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
              {% capture srcset %}{% for i in (1..10) %}{% assign width = 180 | times:i %}{{all_products[product_handle].featured_image | append:'w_' | append:width }} {{width}}w{% unless forloop.last %}, {% endunless %}{% endfor %}{% endcapture %}
              <a href="{{all_products[product_handle].url }}" class="grid-product__link">
                <div class="grid-product__image-mask">
                  <div class="image-wrap">
                    {%- assign img_url = all_products[product_handle].featured_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                    <img class="feature-row__image lazyload"
                         data-src="{{ img_url }}"
                         data-widths="[180, 360, 540, 750, 900, 1080]"
                         data-aspectratio="{{ all_products[product_handle].featured_image.aspect_ratio }}"
                         data-sizes="auto"
                         data-srcset="{{srcset}}"
                         alt="{{ product.title }}">
                  </div>
                {%- assign preview_image = all_products[product_handle].featured_media.preview_image -%}
                {%- assign img_url = preview_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.'-%}
                  {%- if all_products[product_handle].media.size > 1 -%}
                    {%- for media in all_products[product_handle].media offset: 1 limit: 1 -%}
                      {%- assign second_image = media.preview_image -%}
                    {%- endfor -%}
                    <div class="grid-product__secondary-image small--hide">
                      {%- assign img_url = second_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                      <img class="lazyload"
                          data-src="{{ img_url }}"
                          data-widths="[360, 540, 720, 1000]"
                          data-aspectratio="{{ second_image.aspect_ratio }}"
                          data-sizes="auto"
                          alt="{{ second_image.alt }}">
                    </div>
                  {%- endif -%}
                </div>
              </a>
              <div class="product-style__product-info">
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ product_title }}</div>
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ all_products[product_handle].price | money }}</div>
              </div>
            </div>
        {% endfor %}
        {% else %}
          <div class="feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ product_title }}</div>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ all_products[product_handle].price | money }}</div>
          </div>
        {% endif %}
        </div>
      </div>

 

Before this, I also tried just pulling in the metafield straight up via code by just updating the namespace/key but the Shopify metafield must act a little differently than the ACF does because it didn't work.  The namespace for the product reference metafield is "product.metafields.style_with.products" if anyone knows how I would pull it straight in without using a setting.

Accepted Solution (1)
michaelmorgan
Shopify Partner
32 2 5

This is an accepted solution.

Hey Bailey,

 

Thanks for your input but I found a solution! I updated it to the following and it works perfectly:

{%  assign handle = section.settings.featured_products | metafield_tag %}
      
      <div class="product-style-half">
        <div class="product-style__product-grid">
        {% if handle.size > 0 %}
        {% for list_product in section.settings.featured_products %}
            <div class="grid-product__content feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
              {% capture srcset %}{% for i in (1..10) %}{% assign width = 180 | times:i %}{{list_product.featured_image | append:'w_' | append:width }} {{width}}w{% unless forloop.last %}, {% endunless %}{% endfor %}{% endcapture %}
              <a href="{{ list_product.url }}" class="grid-product__link">
                <div class="grid-product__image-mask">
                  <div class="image-wrap">
                    {%- assign img_url = list_product.featured_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                    <img class="feature-row__image lazyload"
                         data-src="{{ img_url }}"
                         data-widths="[180, 360, 540, 750, 900, 1080]"
                         data-aspectratio="{{ list_product.featured_image.aspect_ratio }}"
                         data-sizes="auto"
                         data-srcset="{{srcset}}"
                         alt="{{ list_product.title }}">
                  </div>
                {%- assign preview_image = list_product.featured_media.preview_image -%}
                {%- assign img_url = preview_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.'-%}
                  {%- if list_product.media.size > 1 -%}
                    {%- for media in list_product.media offset: 1 limit: 1 -%}
                      {%- assign second_image = media.preview_image -%}
                    {%- endfor -%}
                    <div class="grid-product__secondary-image small--hide">
                      {%- assign img_url = second_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                      <img class="lazyload"
                          data-src="{{ img_url }}"
                          data-widths="[360, 540, 720, 1000]"
                          data-aspectratio="{{ second_image.aspect_ratio }}"
                          data-sizes="auto"
                          alt="{{ second_image.alt }}">
                    </div>
                  {%- endif -%}
                </div>
              </a>
              <div class="product-style__product-info">
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.title | capitalize }}</div>
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.price | money }}</div>
              </div>
            </div>
        {% endfor %}
        {% else %}
          <div class="feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.title | capitalize }}</div>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.price | money }}</div>
          </div>
        {% endif %}
        </div>
      </div>

Thank you again for reaching out! I really appreciate it!

View solution in original post

Replies 4 (4)

BaileyPaserk
Shopify Partner
116 9 31

Can you show a screenshot of the product list schema setting in the customizer? I did not think it was possible to link the two.

Bailey Paserk

BaileyPaserk
Shopify Partner
116 9 31

Oh I am confused. I am trying to set this up on a demo store for you. Shopify has a single product option and a product list option both for the metafields and for the customizer. Which way are you using this for?

 

 

Bailey Paserk
michaelmorgan
Shopify Partner
32 2 5

I am using the product list option since there will be multiple products. Below is the schema settings for the section.

michaelmorgan_0-1658773714192.jpeg

 

michaelmorgan
Shopify Partner
32 2 5

This is an accepted solution.

Hey Bailey,

 

Thanks for your input but I found a solution! I updated it to the following and it works perfectly:

{%  assign handle = section.settings.featured_products | metafield_tag %}
      
      <div class="product-style-half">
        <div class="product-style__product-grid">
        {% if handle.size > 0 %}
        {% for list_product in section.settings.featured_products %}
            <div class="grid-product__content feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
              {% capture srcset %}{% for i in (1..10) %}{% assign width = 180 | times:i %}{{list_product.featured_image | append:'w_' | append:width }} {{width}}w{% unless forloop.last %}, {% endunless %}{% endfor %}{% endcapture %}
              <a href="{{ list_product.url }}" class="grid-product__link">
                <div class="grid-product__image-mask">
                  <div class="image-wrap">
                    {%- assign img_url = list_product.featured_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                    <img class="feature-row__image lazyload"
                         data-src="{{ img_url }}"
                         data-widths="[180, 360, 540, 750, 900, 1080]"
                         data-aspectratio="{{ list_product.featured_image.aspect_ratio }}"
                         data-sizes="auto"
                         data-srcset="{{srcset}}"
                         alt="{{ list_product.title }}">
                  </div>
                {%- assign preview_image = list_product.featured_media.preview_image -%}
                {%- assign img_url = preview_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.'-%}
                  {%- if list_product.media.size > 1 -%}
                    {%- for media in list_product.media offset: 1 limit: 1 -%}
                      {%- assign second_image = media.preview_image -%}
                    {%- endfor -%}
                    <div class="grid-product__secondary-image small--hide">
                      {%- assign img_url = second_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
                      <img class="lazyload"
                          data-src="{{ img_url }}"
                          data-widths="[360, 540, 720, 1000]"
                          data-aspectratio="{{ second_image.aspect_ratio }}"
                          data-sizes="auto"
                          alt="{{ second_image.alt }}">
                    </div>
                  {%- endif -%}
                </div>
              </a>
              <div class="product-style__product-info">
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.title | capitalize }}</div>
                <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.price | money }}</div>
              </div>
            </div>
        {% endfor %}
        {% else %}
          <div class="feature-row__item feature-row__text feature-row__text--{{ section.settings.layout }}" data-aos>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.title | capitalize }}</div>
            <div class="rte appear-delay{% cycle '','-1','-2','-3','-4' %} h4">{{ list_product.price | money }}</div>
          </div>
        {% endif %}
        </div>
      </div>

Thank you again for reaching out! I really appreciate it!