← back to Dw Contact Us Pages
grid cards: Contact us for pricing on Boost + liquid card paths
6ea5f0529694af035229401e24ca938191a60945 · 2026-09-19 10:10:53 -0700 · Claude (TK-11925)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0163KBzeE1R39RSbxNmAjbki
Files touched
A theme/assets/dw-contact-us-cards.jsA theme/snippets/hide-browse-hidden.liquidA theme/snippets/product-list-item.liquid
Diff
commit 6ea5f0529694af035229401e24ca938191a60945
Author: Claude (TK-11925) <steve@designerwallcoverings.com>
Date: Sat Sep 19 10:10:53 2026 -0700
grid cards: Contact us for pricing on Boost + liquid card paths
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0163KBzeE1R39RSbxNmAjbki
---
theme/assets/dw-contact-us-cards.js | 107 ++++++++++++
theme/snippets/hide-browse-hidden.liquid | 111 +++++++++++++
theme/snippets/product-list-item.liquid | 276 +++++++++++++++++++++++++++++++
3 files changed, 494 insertions(+)
diff --git a/theme/assets/dw-contact-us-cards.js b/theme/assets/dw-contact-us-cards.js
new file mode 100644
index 0000000..68ecfc7
--- /dev/null
+++ b/theme/assets/dw-contact-us-cards.js
@@ -0,0 +1,107 @@
+/* dw-contact-us-cards.js — TK-11925
+ * Boost SD renders every browse/search grid CLIENT-SIDE, so neither
+ * product-list-item.liquid nor a server-rendered rule can reach those cards.
+ * This sweeps Boost cards and replaces the price with "Contact us for pricing"
+ * for the contact-us vendor cohort (Designers Guild / Ralph Lauren /
+ * Christian Lacroix Europe).
+ *
+ * VENDOR-KEYED (preferred): a live Boost card exposes its vendor as the text of
+ * a [class*="product-vendor"] node — measured on the live store, and the same
+ * hook the existing Newmor guard in layout/theme.liquid already relies on
+ * (isNewmor() reads exactly that node). Price nodes measured on the same guard:
+ * .boost-sd__product-price, .boost-sd__format-currency, [class*="compare-price"], [class*="unit-price"]
+ *
+ * Vendor list comes from window.DW_CONTACT_US_VENDORS, emitted by
+ * snippets/hide-browse-hidden.liquid from (in priority order)
+ * 1. shop metafield custom.contact_us_vendors
+ * 2. theme setting settings.contact_us_vendors
+ * 3. the literal 3-vendor fallback
+ * mirroring the showroom_vendors pattern. No id list is baked in, so the
+ * cohort can change without regenerating this asset.
+ *
+ * Optional id backstop: window.DW_CONTACT_US_IDS (array of product ids) is
+ * honoured if present, for cards whose vendor node is suppressed by a Boost
+ * theme setting.
+ */
+(function () {
+ if (window.__dwContactUsCards) return;
+ window.__dwContactUsCards = true;
+
+ var LABEL = 'Contact us for pricing';
+ var CARD_SEL = '.boost-sd__product-item';
+ var PRICE_SEL = '.boost-sd__product-price,.boost-sd__format-currency,[class*="product-price"],[class*="compare-price"],[class*="unit-price"]';
+ var VENDOR_SEL = '[class*="product-vendor"]';
+
+ function norm(s) { return String(s == null ? '' : s).trim().toLowerCase(); }
+
+ var VENDORS = (window.DW_CONTACT_US_VENDORS || [
+ 'Designers Guild', 'Ralph Lauren', 'Christian Lacroix Europe'
+ ]).map(norm).filter(Boolean);
+
+ var IDS = new Set((window.DW_CONTACT_US_IDS || []).map(String));
+
+ if (!VENDORS.length && !IDS.size) return;
+
+ function isTarget(card) {
+ var id = card.getAttribute('data-product-id');
+ if (id && IDS.has(String(id))) return true;
+ var v = card.querySelector(VENDOR_SEL);
+ if (v && VENDORS.indexOf(norm(v.textContent)) > -1) return true;
+ return false;
+ }
+
+ function treat(card) {
+ if (card.getAttribute('data-dw-contact-us') === '1') return;
+ card.setAttribute('data-dw-contact-us', '1');
+
+ var replaced = false;
+ card.querySelectorAll(PRICE_SEL).forEach(function (n) {
+ if (!replaced) {
+ // Reuse the first price node so the card keeps its layout/typography.
+ n.textContent = LABEL;
+ n.classList.add('dw-cu-card-price');
+ n.setAttribute('data-dw-contact-us-price', '1');
+ replaced = true;
+ } else {
+ n.remove();
+ }
+ });
+
+ if (!replaced && !card.querySelector('.dw-cu-card-price')) {
+ var p = document.createElement('p');
+ p.className = 'dw-cu-card-price';
+ p.setAttribute('data-dw-contact-us-price', '1');
+ p.textContent = LABEL;
+ card.appendChild(p);
+ }
+
+ // Nothing purchasable from the grid for this cohort.
+ card.querySelectorAll('[class*="quick-view"],[class*="quickView"],[class*="quick-add"],[class*="buy-now"],[class*="add-to-cart"]')
+ .forEach(function (n) { n.remove(); });
+ }
+
+ var pending = false;
+ function sweep() {
+ var cards = document.querySelectorAll(CARD_SEL + ':not([data-dw-contact-us])');
+ for (var i = 0; i < cards.length; i++) {
+ if (isTarget(cards[i])) treat(cards[i]);
+ }
+ }
+ function schedule() {
+ if (pending) return;
+ pending = true;
+ requestAnimationFrame(function () { pending = false; sweep(); });
+ }
+ function start() {
+ sweep();
+ new MutationObserver(schedule).observe(document.documentElement, { childList: true, subtree: true });
+ }
+
+ var css = document.createElement('style');
+ css.textContent = '.dw-cu-card-price{font-size:12px!important;letter-spacing:.02em;color:#6b6357!important;margin:4px 0 0}' +
+ '.boost-sd__product-item[data-dw-contact-us] .boost-sd__format-currency:not([data-dw-contact-us-price]){display:none!important}';
+ (document.head || document.documentElement).appendChild(css);
+
+ if (document.readyState !== 'loading') start();
+ else document.addEventListener('DOMContentLoaded', start);
+})();
diff --git a/theme/snippets/hide-browse-hidden.liquid b/theme/snippets/hide-browse-hidden.liquid
new file mode 100644
index 0000000..6957b4b
--- /dev/null
+++ b/theme/snippets/hide-browse-hidden.liquid
@@ -0,0 +1,111 @@
+{% comment %}
+ Suppress showroom-only vendors from ALL browse/search grids. TK-11186.
+
+ DATA-DRIVEN — no vendor name is hardcoded in logic. The showroom-vendor list is
+ sourced (in priority order) from:
+ 1. shop metafield custom.showroom_vendors (comma-separated; store-wide, all themes)
+ 2. theme setting settings.showroom_vendors (comma-separated)
+ 3. a canonical fallback snapshot of ~/Projects/fix-live-board/config/showroom-vendors.json
+ (last resort so suppression never silently fails if 1+2 are unset).
+ Canonical source of truth = showroom-vendors.json. Set the shop metafield to that
+ file's contents (metafield-update skill) and this snippet follows it automatically.
+
+ Two layers:
+ (a) RENDER-TIME: product-list-item.liquid emits NO card HTML for a showroom vendor
+ (the real fix — no SEO-crawlable markup, no flash). This snippet's CSS also
+ hides any card that carries data-vendor at paint time (before JS).
+ (b) BACKSTOP: a JS observer catches Boost AJAX-rendered grids that bypass Liquid,
+ reading the SAME injected list (case-insensitive). Kept minimal.
+{% endcomment %}
+{%- liquid
+ assign showroom_raw = shop.metafields.custom.showroom_vendors
+ if showroom_raw == blank
+ assign showroom_raw = settings.showroom_vendors
+ endif
+ if showroom_raw == blank
+ assign showroom_raw = 'Phillip Jeffries'
+ endif
+ assign showroom_vendors = showroom_raw | split: ','
+-%}
+<style>
+{%- for v in showroom_vendors -%}
+{%- assign vt = v | strip -%}
+{%- if vt != blank -%}
+[data-vendor="{{ vt | escape }}"]{display:none!important;}
+{%- endif -%}
+{%- endfor -%}
+/* TK-11307: product-level 'Showroom' tag hook — a shared-vendor showroom line (MDC under
+ 'Phillipe Romano') carries this attr/class without exposing a hideable vendor name. */
+[data-showroom="true"],.pr-showroom-hidden{display:none!important;}
+</style>
+<script>
+(function(){
+ var SHOWROOM_TAG = 'showroomonly'; // TK-11307 — mirrors fix-live-board/config/showroom-vendor.cjs SHOWROOM_TAG
+ var HIDDEN = [{%- for v in showroom_vendors -%}{%- assign vt = v | strip -%}{%- if vt != blank -%}{{ vt | json }}{%- unless forloop.last -%},{%- endunless -%}{%- endif -%}{%- endfor -%}].map(function(s){return String(s).trim().toLowerCase();});
+ if (!HIDDEN.length) return;
+ var CARD_SEL = '.product-list-item, .boost-sd__product-item, [class*="product-item"], [class*="product-card"], article, .boost-sd__product';
+ function isHidden(text){ text = (text||'').trim().toLowerCase(); for (var i=0;i<HIDDEN.length;i++){ if (text.indexOf(HIDDEN[i]) > -1) return true; } return false; }
+ function hideProducts(){
+ document.querySelectorAll('.product-vendor, .product-list-item-vendor, [class*="vendor"]').forEach(function(el){
+ if (isHidden(el.textContent)){ var c = el.closest(CARD_SEL); if (c && c.style.display !== 'none') c.style.display = 'none'; }
+ });
+ document.querySelectorAll('.product-list-item-title a, .boost-sd__product-title a, [class*="product-title"] a, h2 a, h3 a').forEach(function(el){
+ if (isHidden(el.textContent)){ var c = el.closest(CARD_SEL); if (c && c.style.display !== 'none') c.style.display = 'none'; }
+ });
+ document.querySelectorAll('[data-vendor]').forEach(function(el){
+ if (HIDDEN.indexOf(String(el.getAttribute('data-vendor')||'').trim().toLowerCase()) > -1){ el.style.display = 'none'; }
+ });
+ // TK-11307: the product-level showroom hide is NOT done here.
+ // A data-tags hook used to live in this function. It was dead code — no product card on
+ // this store emits data-tags (measured: 59 cards across 4 surfaces, 0 data-tags) — and it
+ // was actively dangerous, because an earlier revision split tags on WHITESPACE and matched
+ // 'showroom', which makes the unrelated 'Showroom Line' tag on 18,518+ ACTIVE SELLABLE
+ // products (Kravet, China Seas, Scalamandre, Osborne & Little, sellable Phillipe Romano...)
+ // tokenize to ['showroom','line'] and MATCH. Leaving a dead hook in place invites someone
+ // to "make it work" by emitting data-tags, which arms exactly that landmine.
+ // Browse grids here are rendered by Boost SD, not Liquid, so the working mechanism is the
+ // id-keyed asset included below — see assets/dw-showroom-hide.js.
+ }
+ hideProducts();
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', hideProducts);
+ setInterval(hideProducts, 2000);
+ if (document.body){ new MutationObserver(function(){ setTimeout(hideProducts, 100); }).observe(document.body, { childList:true, subtree:true }); }
+})();
+</script>
+
+{%- comment -%}
+ TK-11307 — product-level showroom-only hide for Boost-rendered browse grids.
+ Boost renders every browse/search grid client-side, so neither product-list-item.liquid nor
+ the observer above can reach those cards; a rendered Boost card exposes only data-product-id
+ (no tags). dw-showroom-hide.js is GENERATED from the live 'ShowroomOnly' tag by
+ scripts/tk11307-showroom-tag/build-showroom-hide-asset.mjs and matches on that id.
+ It deliberately no-ops on /search and ?q= so the line stays findable on-site — Steve's rule
+ is "addressable but not discoverable". Regenerate the asset whenever the tagged set changes.
+{%- endcomment -%}
+<script src="{{ 'dw-showroom-hide.js' | asset_url }}" defer></script>
+
+{%- comment -%}
+ TK-11925 — "contact us" pricing treatment for Boost-rendered browse/search grids.
+ Boost renders those grids client-side, so the Liquid path in product-list-item.liquid
+ never runs for them. dw-contact-us-cards.js sweeps .boost-sd__product-item cards and
+ swaps the price for "Contact us for pricing" for the vendors listed below.
+
+ DATA-DRIVEN, mirroring the showroom_vendors pattern above:
+ 1. shop metafield custom.contact_us_vendors (comma-separated; store-wide)
+ 2. theme setting settings.contact_us_vendors (comma-separated)
+ 3. literal fallback: Designers Guild, Ralph Lauren, Christian Lacroix Europe
+{%- endcomment -%}
+{%- liquid
+ assign contact_us_raw = shop.metafields.custom.contact_us_vendors
+ if contact_us_raw == blank
+ assign contact_us_raw = settings.contact_us_vendors
+ endif
+ if contact_us_raw == blank
+ assign contact_us_raw = 'Designers Guild,Ralph Lauren,Christian Lacroix Europe'
+ endif
+ assign contact_us_vendors = contact_us_raw | split: ','
+-%}
+<script>
+window.DW_CONTACT_US_VENDORS = [{%- for v in contact_us_vendors -%}{%- assign vt = v | strip -%}{%- if vt != blank -%}{{ vt | json }}{%- unless forloop.last -%},{%- endunless -%}{%- endif -%}{%- endfor -%}];
+</script>
+<script src="{{ 'dw-contact-us-cards.js' | asset_url }}" defer></script>
diff --git a/theme/snippets/product-list-item.liquid b/theme/snippets/product-list-item.liquid
new file mode 100644
index 0000000..14bd6e8
--- /dev/null
+++ b/theme/snippets/product-list-item.liquid
@@ -0,0 +1,276 @@
+{% comment %}
+ @param product_attributes
+ custom attributes to be applied to the product item
+ Defaults to: blank
+{% endcomment %}
+
+{%- comment %} TK-11186 render-time showroom-vendor skip: emit NO card HTML for a showroom-only
+ vendor (addressable-not-discoverable). List sourced from shop metafield / theme setting /
+ canonical showroom-vendors.json fallback — never a hardcoded vendor. {% endcomment -%}
+{%- liquid
+ assign showroom_raw = shop.metafields.custom.showroom_vendors
+ if showroom_raw == blank
+ assign showroom_raw = settings.showroom_vendors
+ endif
+ if showroom_raw == blank
+ assign showroom_raw = 'Phillip Jeffries'
+ endif
+ assign showroom_vendors = showroom_raw | split: ','
+ assign this_vendor = product.vendor | strip | downcase
+ assign is_showroom_vendor = false
+ for sv in showroom_vendors
+ assign svn = sv | strip | downcase
+ if svn != blank and svn == this_vendor
+ assign is_showroom_vendor = true
+ endif
+ endfor
+ # TK-11307: product-level 'Showroom' TAG is an ADDITIONAL, shared-vendor-safe key.
+ # A showroom line under a SHARED private label (MDC under 'Phillipe Romano', which also
+ # carries sellable lines) is suppressed by its own tag WITHOUT hiding the vendor. The
+ # tag applier stamps 'Showroom' on exactly the showroom products; sellable siblings keep
+ # rendering. Case-insensitive: check both 'Showroom' and 'showroom'.
+ if product.tags contains 'Showroom' or product.tags contains 'showroom'
+ assign is_showroom_vendor = true
+ endif
+-%}
+{%- unless is_showroom_vendor -%}
+
+{% liquid
+ assign product_attributes = product_attributes | default: ''
+ assign product_hover = settings.product_hover | default: 'quick-shop'
+ assign product_stock_level_threshold = settings.product_stock_level_threshold | default: 1
+ assign product_badges = settings.product_badges | default: false
+ assign product_icons = settings.product_badges_icons | default: false
+ assign product_vendor = settings.show_vendor | default: false
+
+ assign item = product
+ if template contains 'search'
+ assign item = item
+ endif
+
+ assign has_quick_shop = false
+ if product_hover == 'quick-shop' and template.name != 'password' and product.variants_count <= 250 and product.vendor != 'Newmor Wallcoverings'
+ assign has_quick_shop = true
+ endif
+%}
+
+{% if product_hover == 'stock-level' and item.available %}
+ {% assign total = 0 %}
+ {% assign threshold = product_stock_level_threshold | times: 1 %}
+ {% assign infinity = false %}
+ {% for variant in item.variants %}
+ {% if variant.inventory_management == null %}
+ {% assign infinity = true %}
+ {% elsif variant.inventory_management == '' %}
+ {% assign infinity = true %}
+ {% elsif variant.inventory_management == 'shopify' and variant.inventory_policy == 'continue' %}
+ {% assign infinity = true %}
+ {% elsif infinity == false %}
+ {% capture temp %}{{ total | plus: variant.inventory_quantity }}{% endcapture %}
+ {% assign total = temp | times: 1 %}
+ {% endif %}
+ {% endfor %}
+ {% assign stockText = 'products.product.stock_indicator_message' | t: num: total %}
+{% endif %}
+
+<article
+ class="
+ product-list-item
+ {% if has_quick_shop %} has-quick-shop{% endif %}
+ {% if item.available and infinity == false and total <= threshold %} has-stock-indicator{%endif %}
+ "
+ id="product-list-item-{{ item.id }}"
+ data-product-id="{{ item.id }}"
+ {{ product_attributes }}
+>
+
+ {% assign secondaryImage = false %}
+ {% if item.media.size > 1 and product_hover == 'image-flip' %}
+ {% assign secondaryImage = true %}
+ {% endif %}
+
+ <figure
+ class="
+ product-list-item-thumbnail
+ {% if secondaryImage %}
+ has-secondary-image
+ {% endif %}
+ "
+ data-url="{{ item.url | within: collection }}"
+ {% if secondaryImage %}
+ {%
+ render 'rimg',
+ img: item.media[1].preview_image,
+ alt: item.media[1].preview_image.alt,
+ size: '600x600',
+ background: true,
+ lazy: true
+ %}
+ {% endif %}
+ >
+ <a href="{{ item.url | within: collection }}" aria-label="{{ item.title }}">
+ {% if item.featured_media.preview_image %}
+ {%
+ render 'rimg',
+ img: item.featured_media.preview_image,
+ alt: item.featured_media.preview_image.alt,
+ size: '600x600',
+ lazy: true
+ %}
+ {% else %}
+ {{ 'product-1' | placeholder_svg_tag: 'placeholder-svg' }}
+ {% endif %}
+
+ <div class="product-info">
+ <div class="vertical-center">
+ <div>View Pattern</div>
+ {%- liquid
+ assign sku_raw = item.variants.last.sku | default: ''
+ assign sku_display = sku_raw | replace: '-Sample', '' | replace: '-SAMPLE', '' | replace: '-sample', ''
+ assign sku_display = sku_display | replace: '--', '-' | replace: '--', '-'
+ assign sku_last_char = sku_display | slice: -1, 1
+ if sku_display != blank and sku_last_char == '-'
+ assign sku_display = sku_display | remove_last: '-'
+ endif
+ -%}
+ <div>{{ sku_display }}</div>
+ </div>
+ </div>
+
+ </a>
+
+ {% if has_quick_shop %}
+ <span
+ class="quick-shop-modal-trigger"
+ data-product-url="{{ item.url | within: collection }}"
+ >
+ {{ 'products.product.quick_shop_trigger_text' | t }}
+ </span>
+ {% elsif product_hover == 'stock-level' %}
+
+ {% if item.available and infinity == false and total <= threshold %}
+ <a class="product-list-item-inventory" href="{{ item.url }}">{{ stockText }}</a>
+ {% endif %}
+
+ {% endif %}
+
+ {% if product_badges %}
+ {% if item.available != true %}
+ <span class="product-list-item-unavailable{% if product_icons %} product-icons{% endif %}" data-title="{{ 'products.product.sold_out' | t }}"></span>
+ {% elsif item.compare_at_price_min > item.price_min %}
+ <span class="product-list-item-on-sale{% if product_icons %} product-icons{% endif %}" data-title="{{ 'products.product.on_sale' | t }}"></span>
+ {% endif %}
+ {% endif %}
+ </figure>
+
+ <div class="product-list-item-details">
+ {% if product_vendor %}
+ <p class="product-list-item-vendor">{{ item.vendor | link_to_vendor }}</p>
+ {% endif %}
+ <h2 class="product-list-item-title"><a href="{{ item.url | within: collection }}">{{ item.title }}</a></h2>
+
+ {%- comment -%}
+ DW grid-card color swatch (Carnegie-restructure fix, TK-10686).
+ Additive: renders ONLY when a valid hex metafield exists, so non-Carnegie
+ cards are unaffected. Reads hex + name across the lowercase, space-cased,
+ and swatch_hex key variants so the Carnegie Xorel restructure is covered.
+ Pure Liquid, fixed dimensions (no CLS), no shared DOM ids (grid-safe).
+ {%- endcomment -%}
+ {%- liquid
+ assign dw_hex = item.metafields.custom.color_hex.value | default: item.metafields.custom['Color Hex'].value | default: item.metafields.custom.swatch_hex.value | default: item.metafields.custom.primary_color_hex.value
+ assign dw_color_name = item.metafields.custom.color_name.value | default: item.metafields.custom.color.value | default: item.metafields.custom['Color'].value | default: item.metafields.global['Color'].value
+ assign dw_hex_body = dw_hex | strip | remove_first: '#'
+ assign dw_hex_len = dw_hex_body | size
+ assign dw_hex_ok = false
+ if dw_hex_len == 6
+ assign dw_hex_ok = true
+ elsif dw_hex_len == 3
+ assign dw_hex_ok = true
+ endif
+ -%}
+ {%- if dw_hex_ok -%}
+ <p class="product-list-item-swatch" style="display:flex;align-items:center;gap:8px;margin:4px 0 2px;line-height:1;">
+ <span class="product-list-item-swatch-dot" aria-hidden="true" style="display:inline-block;width:16px;height:16px;min-width:16px;border-radius:50%;background:#{{ dw_hex_body | escape }};border:1px solid rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.08);flex:0 0 auto;"></span>
+ {%- if dw_color_name != blank -%}
+ <span class="product-list-item-swatch-name" style="font-size:0.82em;color:#555;">{{ dw_color_name | escape }}</span>
+ {%- endif -%}
+ </p>
+ {%- endif -%}
+
+ {%- comment -%} TK-11925: liquid-rendered card path for the contact-us cohort
+ (Designers Guild / Ralph Lauren / Christian Lacroix Europe). Keyed on the product's
+ TEMPLATE SUFFIX, not a vendor literal, so the card follows whatever set
+ scripts/assign-template.mjs has stamped — no second list to keep in sync.
+ Boost-rendered grids are handled by assets/dw-contact-us-cards.js. {%- endcomment -%}
+ {% if item.template_suffix == 'contact-us' %}
+ <p class="product-list-item-price dw-cu-card-price" data-dw-contact-us-price>Contact us for pricing</p>
+ {% elsif item.vendor == 'Newmor Wallcoverings' %}
+ <p class="product-list-item-price" data-newmor-showroom>Showroom inquiry</p>
+ {% else %}
+ <p class="product-list-item-price">
+ {% if item.price_varies %}
+ {% if item.price_varies %}{{ 'products.product.from' | t }}{% endif %}
+ {% if item.compare_at_price_min > item.price_min %}
+ <span class="money">{{ item.price_min | money }}</span>
+ <span class="original money">{{ item.compare_at_price_min | money }}</span>
+ {% else %}
+ <span class="money">{{ item.price_min | money }}</span>
+ {% endif %}
+ {% else %}
+ {% if item.compare_at_price_min > item.price_min %}
+ <span class="money">{{ item.price_min | money }}</span>
+ <span class="original money">{{ item.compare_at_price_min | money }}</span>
+ {% else %}
+ <span class="money">{{ item.price_min | money }}</span>
+ {% endif %}
+ {% endif %}
+ </p>
+ {% assign variant_for_unit_price = item.variants | sort: 'price' | first %}
+ {% if variant_for_unit_price.unit_price %}
+ {% comment %}Inject unit-price begin{% endcomment %}
+ {% comment %}
+ @param variant_for_unit_price
+ Product variant for price
+ @param tax_text
+ String containing 'tax included' text
+ {% endcomment %}
+
+ {% capture total_quantity %}
+ <span class="product-price__unit-price-total-quantity" data-unit-price-quantity>
+ {{ variant_for_unit_price.unit_price_measurement.quantity_value }}{{ variant_for_unit_price.unit_price_measurement.quantity_unit }}
+ </span>
+ {% endcapture %}
+
+
+ {% capture unit_price %}
+ <span class="product-price__unit-price-amount money" data-unit-price-amount>
+ {{ variant_for_unit_price.unit_price | money }}
+ </span>
+ {% endcapture %}
+ {% capture unit_measure %}
+ <span class="product-price__unit-price-measure" data-unit-price-measure>
+ {%- if variant_for_unit_price.unit_price_measurement.reference_value != 1 -%}
+ {{ variant_for_unit_price.unit_price_measurement.reference_value }}
+ {%- endif %}
+ {{ variant_for_unit_price.unit_price_measurement.reference_unit }}
+ </span>
+ {% endcapture %}
+
+ <div
+ class="
+ product-price__unit-price
+ {% unless variant_for_unit_price.unit_price_measurement %}hidden{% endunless %}
+ "
+ data-unit-price
+ >
+ {{ 'products.product.price_per_unit_html' | t: total_quantity: total_quantity, unit_price: unit_price, unit_measure: unit_measure | strip_newlines }}
+ </div>
+
+ {% assign variant_for_unit_price = blank %}
+ {% comment %}Inject unit-price end{% endcomment %}
+
+ {% endif %}
+ {% endif %}
+ </div>
+
+</article>{%- endunless -%}
← 6660ec4 product.liquid: render contact block directly below the imag
·
back to Dw Contact Us Pages
·
scripts: shared lib + read-only enumerate (785 targets captu fa643c4 →