← back to Newmor Onboard

data/live-2026-09-09/theme/sections/product.liquid

419 lines

{% render 'breadcrumbs' %}

{% liquid
  assign enable_zoom = section.settings.enable_zoom
  assign enable_cart_redirection = section.settings.enable_cart_redirection
  assign images_layout = section.settings.images_layout
  assign enable_video_autoplay = section.settings.enable_video_autoplay
  assign enable_video_looping = section.settings.enable_video_looping
  assign enable_linked_options = true
  assign show_vendor = settings.show_vendor
  assign show_social_media_icons = section.settings.show_social_media_icons
  assign show_payment_button = section.settings.show_payment_button

  for block in section.blocks
    if block.type == 'complementary_products'
      assign product_recommendation_limit = block.settings.product_recommendation_limit
      break
    endif
  endfor
%}

{% if images_layout == 'masonry' %}
  {% comment %}Related products in masonry grid must be below product{% endcomment %}
  {% assign related_products_position_right = false %}
{% endif %}

<script
  type="application/json"
  data-section-type="product"
  data-section-id="{{ section.id }}"
  data-section-data
>
  {
    "product": {{ product | json }},
    "product_settings": {
      "addToCartText": {{ 'products.product.add_to_cart' | t | json }},
      "enableHistory": true,
      "processingText": {{ 'products.product.processing' | t | json }},
      "setQuantityText": {{ 'products.product.set_quantity' | t | json }},
      "soldOutText": {{ 'products.product.sold_out' | t | json }},
      "unavailableText": {{ 'products.product.unavailable' | t | json }}
    },
    "images_layout": {{ images_layout | json }},
    "enable_zoom": {{ enable_zoom | json }},
    "enable_video_autoplay": {{ enable_video_autoplay | json }},
    "enable_video_looping": {{ enable_video_looping | json }},
    "enable_cart_redirection": {{ enable_cart_redirection | json }},
    "enable_fixed_positioning": true,
    "product_recommendation_limit": {{ product_recommendation_limit | json }}
  }
</script>

{% render 'product-success-labels' %}
<section class="product-container">
  {%
    render 'product',
    product: product,
    enable_zoom: enable_zoom,
    images_layout: images_layout,
    enable_linked_options: enable_linked_options,
    show_vendor: show_vendor,
    show_social_media_icons: show_social_media_icons,
    show_payment_button: show_payment_button,
  %}

  {%- comment -%} "How Many Rolls?" AR deep-link button — Council idea #5, PATH B (TK-10385).
     Rendered directly below the product form (Add-to-Cart / sample block, from the 'product'
     snippet above). Hard reliability gate lives in the snippet: renders NOTHING unless a
     numeric width metafield is present. {%- endcomment -%}
  {% render 'how-many-rolls' %}

  {%- comment -%} Select Color for Coordinates (color-palette) — full-width, below the two-column
     block, ABOVE "More Wallcoverings". Clicking a color serves coordinating products in a 2-row
     full-width grid right under the bar (Steve 2026-07-28). {%- endcomment -%}
  {% render 'color-palette' %}

  {%- comment -%} More Wallcoverings Like This — full-width CLIP similarity row, moved here from the color-palette snippet so it spans the whole page below the two-column block (Steve 2026-07-28). {%- endcomment -%}
{%- comment -%} CLIP "More like this" — PDP color-dot CLIP visual-similarity row.
  Calls the SAME-BEHAVIOR public proxy /apps/similar (dwphoto → loopback CLIP :9914),
  which returns the visually-nearest patterns to THIS product, softly re-ranked by the
  same hex→color-family bucket + style overlap the swatches use. Additive: the swatch
  spectrum + its color-family links above are unchanged. dw_sku / hex / style come from
  the product's REAL fields. (Steve "ship the CLIP dots" 2026-07-08) {%- endcomment -%}
{%- assign _dw_sku = product.selected_or_first_available_variant.sku | default: product.variants.first.sku | remove: '-Sample' -%}
{%- assign _dw_hex = product.metafields.custom.primary_color_hex.value | default: product.metafields.custom.color_hex.value | default: product.metafields.dwc.dominant_hex.value -%}
{%- assign _dw_style = product.metafields.custom.style.value | default: product.metafields.global.Style.value | default: product.type -%}
{%- if _dw_sku != blank -%}
<div id="dw-similar" class="dw-similar"
     data-dw-sku="{{ _dw_sku | escape }}"
     data-hex="{{ _dw_hex | escape }}"
     data-style="{{ _dw_style | escape }}"
     data-endpoint="https://photo.designerwallcoverings.com/apps/similar">
  <h3 class="dw-similar__h">Coordinating Products</h3>
  <div class="dw-similar__grid" aria-live="polite"></div>
</div>
<script>
(function(){
  var root=document.getElementById('dw-similar'); if(!root) return;
  var sku=(root.dataset.dwSku||'').trim().replace(/-Sample$/i,'');  // base SKU keys the CLIP index; the Sample variant SKU (usually first-available) has no embedding
  if(!sku){ root.style.display='none'; return; }
  var ep=root.dataset.endpoint||'https://photo.designerwallcoverings.com/apps/similar';
  fetch(ep,{method:'POST',mode:'cors',headers:{'Content-Type':'application/json'},
    body:JSON.stringify({dw_sku:sku, hex:root.dataset.hex||'', style:root.dataset.style||'', k:12})})
   .then(function(r){return r.ok?r.json():{results:[]};})
   .then(function(d){
     var g=root.querySelector('.dw-similar__grid');
     if(!d.results||!d.results.length){ root.style.display='none'; return; }
     d.results.forEach(function(p){
       var a=document.createElement('a'); a.className='dw-similar__card'; a.rel='nofollow';
       // real PDP link when we have a storefront handle; else fall back to a SKU search (never a name-search)
       a.href = p.handle ? ('/products/'+encodeURIComponent(p.handle))
                         : ('/search?q='+encodeURIComponent(p.dw_sku||'')+'&type=product');
       var img=document.createElement('img'); img.loading='lazy'; img.src=p.image||''; img.alt=p.pattern||'';
       var cap=document.createElement('span'); cap.className='dw-similar__cap'; cap.textContent=p.pattern||'';
       a.appendChild(img); a.appendChild(cap); g.appendChild(a);
     });
   }).catch(function(){ root.style.display='none'; });
})();
</script>
<style>
/* Steve 2026-07-28: relocated OUT of the left gallery column to span the full page width.
   DTD design-panel verdict A (front-page-steward + ui-ux-designer): clear:both makes the
   full-width band collision-proof against the two-column block (specs) even if the theme
   floats its columns — the strip always drops fully below both columns. */
.dw-similar{clear:both;margin:34px auto 10px;max-width:1200px;width:100%;text-align:center;padding:0 20px;box-sizing:border-box}
.dw-similar__h{font-family:Lora,serif;font-size:17px;font-weight:500;color:#3D4246;letter-spacing:-0.01em;margin:0 0 16px}
/* Steve 2026-07-28: LARGER, uniform cards. min-width:0 on the card is the fix for the
   grid "blowout" — without it, a 1fr track's implicit min-content minimum lets a large
   natural image (e.g. 2520px) force its column wider than the others, so cards rendered
   at different sizes. With min-width:0 every 1fr track shrinks equally → all cards identical. */
.dw-similar__grid{display:grid!important;grid-template-columns:repeat(auto-fill,minmax(190px,1fr))!important;gap:18px!important}
@media(min-width:1200px){.dw-similar__grid{grid-template-columns:repeat(6,1fr)!important}}
/* FORCE every card identical (Steve 2026-07-28): min-width:0 !important defeats the grid
   min-content blowout AND any theme img rule, so cards are ALWAYS the same size. */
.dw-similar__card{display:block!important;text-decoration:none;color:inherit;min-width:0!important;width:auto!important;max-width:none!important}
.dw-similar__card img{width:100%!important;height:auto!important;aspect-ratio:1/1!important;object-fit:cover!important;display:block!important;min-width:0!important;max-width:100%!important;border:1px solid #e5e5e5;border-radius:3px}
.dw-similar__cap{display:block;font-family:Lora,serif;font-size:11px;color:#3D4246;margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:capitalize}
.dw-similar:empty{display:none}
</style>
{%- endif -%}

  {%- comment -%} Design Coordinate feature removed from the PDP (Steve 2026-07-28, DTD: "remove feature entirely"). {%- endcomment -%}

  <div
    class="product-recommendations-wrapper--right"
    data-product-recommendations-right
  >
  </div>
</section>

{% schema %}
{
  "name": "Product pages",
  "settings": [
    {
      "type": "checkbox",
      "id": "enable_cart_redirection",
      "label": "Enable cart redirection",
      "info": "Automatically sends users to the Cart page after adding a product.",
      "default": false
    },
    {
      "type": "checkbox",
      "id": "show_payment_button",
      "label": "Show dynamic checkout button",
      "info": "Each customer will see their preferred payment method from those available on your store, such as PayPal or Apple Pay. [Learn more](https://help.shopify.com/manual/using-themes/change-the-layout/dynamic-checkout)",
      "default": true
    },
    {
      "type": "header",
      "content": "Media"
    },
    {
      "type": "paragraph",
      "content": "Learn more about [media types](https://help.shopify.com/en/manual/products/product-media/product-media-types)"
    },
    {
      "type": "select",
      "id": "images_layout",
      "label": "Layout",
      "options": [
        {
          "label": "Slideshow",
          "value": "slideshow"
        },
        {
          "label": "List",
          "value": "list"
        },
        {
          "label": "Masonry",
          "value": "masonry"
        }
      ],
      "default": "slideshow"
    },
    {
      "type": "checkbox",
      "id": "enable_zoom",
      "label": "Enable image zoom",
      "info": "Zoom only works with the slideshow image layout"
    },
    {
      "type": "checkbox",
      "id": "enable_video_autoplay",
      "label": "Enable video autoplay",
      "default": true
    },
    {
      "type": "checkbox",
      "id": "enable_video_looping",
      "label": "Enable video looping"
    }
  ],
  "blocks": [
    {
      "type": "@app"
    },
    {
      "type": "collapsible-tab",
      "name": "Collapsible tab",
      "settings": [
        {
          "type": "text",
          "id": "collapsible_tab_heading",
          "label": "Heading",
          "default": "Collapsible tab"
        },
        {
          "type": "richtext",
          "id": "collapsible_tab_text",
          "label": "Text",
          "default": "<p>Use this text to share information about your product.</p>"
        }
      ]
    },
    {
      "type": "custom-liquid",
      "name": "Custom liquid",
      "settings": [
        {
          "type": "liquid",
          "id": "custom_liquid",
          "label": "Custom liquid",
          "info": "Add app snippets or other Liquid code to create advanced customizations."
        }
      ]
    },
    {
      "type": "tabs",
      "name": "Tabs",
      "limit": 1,
      "settings": [
        {
          "type": "checkbox",
          "id": "show_product_description",
          "label": "Show product description",
          "default": false
        },
        {
          "type": "header",
          "content": "Tab"
        },
        {
          "type": "text",
          "id": "tab_heading_1",
          "label": "Heading",
          "default": "Tab 1"
        },
        {
          "type": "richtext",
          "id": "tab_text_1",
          "label": "Text",
          "default": "<p>Tab 1 content goes here.</p>"
        },
        {
          "type": "header",
          "content": "Tab"
        },
        {
          "type": "text",
          "id": "tab_heading_2",
          "label": "Heading",
          "default": "Tab 2"
        },
        {
          "type": "richtext",
          "id": "tab_text_2",
          "label": "Text",
          "default": "<p>Tab 2 content goes here.</p>"
        },
        {
          "type": "header",
          "content": "Tab"
        },
        {
          "type": "text",
          "id": "tab_heading_3",
          "label": "Heading",
          "default": "Tab 3"
        },
        {
          "type": "richtext",
          "id": "tab_text_3",
          "label": "Text",
          "default": "<p>Tab 3 content goes here.</p>"
        }
      ]
    },
    {
      "type": "title",
      "name": "Title",
      "limit": 1
    },
    {
      "type": "vendor",
      "name": "Vendor",
      "limit": 1
    },
    {
      "type": "social",
      "name": "Social",
      "limit": 1
    },
    {
      "type": "description",
      "name": "Description",
      "limit": 1
    },
    {
      "type": "price",
      "name": "Price",
      "limit": 1
    },
    {
      "type": "form",
      "name": "Form",
      "limit": 1,
      "settings": [
        {
          "type": "paragraph",
          "content": "Customize form features for the product in the products portion of the theme settings."
        },
        {
          "type": "checkbox",
          "id": "show_gift_card_recipient_form",
          "label": "t:sections.product.blocks.form.show_gift_card_recipient_form.label",
          "info": "t:sections.product.blocks.form.show_gift_card_recipient_form.info",
          "default": false
        }
      ]
    },
    {
      "type": "rating",
      "name": "Product rating",
      "limit": 1,
      "settings": [
        {
          "type": "paragraph",
          "content": "To display a rating, add a product rating app. [Learn more](https://apps.shopify.com/product-reviews)"
        }
      ]
    },
    {
      "type": "complementary_products",
      "name": "Complementary products",
      "limit": 1,
      "settings": [
        {
          "type": "paragraph",
          "content": "To select complementary products, add the Search & Discovery app. [Learn more](https:\/\/shopify.dev\/themes\/product-merchandising\/recommendations)"
        },
        {
          "type": "text",
          "id": "heading",
          "label": "Heading",
          "default": "Pairs well with"
        },
        {
          "type": "range",
          "id": "product_recommendation_limit",
          "label": "Maximum products to show",
          "min": 1,
          "max": 10,
          "default": 5
        },
        {
          "type": "range",
          "id": "products_per_slide",
          "label": "Number of products per page",
          "min": 1,
          "max": 3,
          "default": 2
        }
      ]
    }
  ]
}

{% endschema %}

{%- comment -%} KEYWORDS (Steve 2026-07-28): serve full-width across the entire
  screen. Removed the 80ch cap + the manual 96-char <br> wrapping so the tag links
  now flow and wrap naturally at the full container width. {%- endcomment -%}
<div class="keywords-desktop" style="width: 100%; max-width: none; box-sizing: border-box; padding: 0 3ch; line-height: 1.9; text-align: center;">
  <h4 style="margin: 0 0 6px;">KEYWORDS:</h4>
  <div class="keywords-desktop__list" style="width: 100%;">
    {%- for tag in product.tags -%}
      {%- unless tag == "display_variant" -%}<a href="/search?q={{ tag | url_encode }}">{{ tag }}</a>{%- unless forloop.last -%}, {% endunless -%}{%- endunless -%}
    {%- endfor -%}
  </div>
</div>

{% comment %} Recently Viewed Products — tracks current product + shows carousel {% endcomment %}
{% if settings.dw_enable_recently_viewed %}

  {% render 'recently-viewed' %}
{% endif %}