← back to Council 0809 Builds
rolls-ar-deeplink/work-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 %}