← back to Philipperomano
TK-11304: PDP shows bold 'Type II Commercial Wallcovering' label + per-yard unit (render unit_of_measure, no single-roll hardcode)
8dbe850ab9c15a69fe2a18e4106cfacdbe1e5259 · 2026-09-08 11:54:08 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JDeaFL4eeREBZX79tc4cnr
Files touched
Diff
commit 8dbe850ab9c15a69fe2a18e4106cfacdbe1e5259
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Sep 8 11:54:08 2026 -0700
TK-11304: PDP shows bold 'Type II Commercial Wallcovering' label + per-yard unit (render unit_of_measure, no single-roll hardcode)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JDeaFL4eeREBZX79tc4cnr
---
server.js | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 445b749..403d926 100644
--- a/server.js
+++ b/server.js
@@ -794,10 +794,25 @@ app.get('/', (req, res) => {
res.set('Content-Type','text/html').send(layout(`${cat === 'naturals' ? 'Naturals' : (type || 'All Products')}${q ? ` · ${q}` : ''}`, body, { q, type, cat, canonical, ogImage }));
});
+// TK-11304 — Type II contract-wallcovering detector. Tags-first (array or CSV
+// string) per the standing rule, falling back to title/product_type since the
+// microsite's static dataset predates a tags column. Accepts "Type II" or "Type 2".
+function isTypeII(p) {
+ const hay = [];
+ if (Array.isArray(p.tags)) hay.push(p.tags.join(','));
+ else if (typeof p.tags === 'string') hay.push(p.tags);
+ hay.push(p.title || '', p.product_type || '');
+ return /type\s*(?:ii|2)\b/i.test(hay.join(' | '));
+}
+
app.get('/p/:handle', (req, res) => {
const p = ENRICHED.find(x => x.handle === req.params.handle);
if (!p) return res.status(404).set('Content-Type','text/html').send(layout('Not found', '<main><div class="empty">Product not found.</div></main>'));
+ // Contract goods (Type II) are sold BY THE YARD — render the product's unit
+ // when present, never hardcode a single-roll unit. (unit_of_measure metafield
+ // is corrected upstream; default '/yd' for this per-yard line until it lands.)
+ const unit = p.unit_of_measure ? esc(p.unit_of_measure) : '/yd';
const body = `
<div class="detail">
<div class="hero">${p.image_url ? `<img src="${esc(p.image_url)}" alt="${esc(p.title)}">` : ''}</div>
@@ -805,10 +820,12 @@ app.get('/p/:handle', (req, res) => {
<div class="crumb"><a href="/">Phillipe Romano</a> / ${esc(NORM_TYPE(p.product_type))}</div>
<div class="pt">${esc(NORM_TYPE(p.product_type))}</div>
<h1>${esc(p.title)}</h1>
+ ${isTypeII(p) ? `<div class="type2-label" style="font-weight:700;font-size:15px;color:var(--fg,#1a1714);letter-spacing:.01em;margin:0 0 18px">Type II Commercial Wallcovering</div>` : ''}
<div class="row"><div class="k">SKU</div><div>${esc(p.dw_sku || '—')}</div></div>
${p.mfr_sku ? `<div class="row"><div class="k">Mfr SKU</div><div>${esc(p.mfr_sku)}</div></div>` : ''}
<div class="row"><div class="k">Type</div><div>${esc(p.product_type)}</div></div>
- ${p.retail_price ? `<div class="row"><div class="k">Retail</div><div>$${parseFloat(p.retail_price).toFixed(2)} /yd</div></div>` : ''}
+ ${p.unit_of_measure ? `<div class="row"><div class="k">Sold By</div><div>${esc(p.unit_of_measure)}</div></div>` : ''}
+ ${p.retail_price ? `<div class="row"><div class="k">Retail</div><div>$${parseFloat(p.retail_price).toFixed(2)} ${unit}</div></div>` : ''}
<div class="actions">
<a class="btn-primary" href="${esc(memoSampleUrl(p.handle))}" target="_blank" rel="noopener noreferrer">Order Memo Sample (free)</a>
<a class="btn-secondary" href="${esc(shopifyUrl(p.handle))}" target="_blank" rel="noopener noreferrer">Shop on DW</a>
← 6921423 auto-data-snapshot: 2026-08-28T05:53:21 (2 data files) — dat
·
back to Philipperomano
·
TK-11341: add AdSense Auto-Ads loader + ads.txt (revert to r a99dece →