← back to Handcraftedwallpaper
Revert "rails: tag-aware via shared rail-match helper + editorial LABELS (rescue flat grid)"
09c69d89ea70637da04adb7a880a0b4219800641 · 2026-05-26 10:48:52 -0700 · Steve Abrams
This reverts commit d98385df3559a2c47c46248ac1a652ab7fe7d4ad.
Files touched
M public/index.htmlM server.jsM site.config.json
Diff
commit 09c69d89ea70637da04adb7a880a0b4219800641
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 26 10:48:52 2026 -0700
Revert "rails: tag-aware via shared rail-match helper + editorial LABELS (rescue flat grid)"
This reverts commit d98385df3559a2c47c46248ac1a652ab7fe7d4ad.
---
public/index.html | 39 +++++++++++++++++++++++----------------
server.js | 16 +++++++++-------
site.config.json | 8 ++++++--
3 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/public/index.html b/public/index.html
index bcf4f51..f621636 100644
--- a/public/index.html
+++ b/public/index.html
@@ -333,7 +333,16 @@ textarea:focus-visible,
<section class="section" id="ideas">
- <div id="railsContainer"></div>
+ <div class="rail-block">
+ <div class="rail-eyebrow">Ideas</div>
+ <h2 class="rail-title">New this week</h2>
+ <div class="rail" id="railNewest"></div>
+ </div>
+ <div class="rail-block">
+ <div class="rail-eyebrow">Ideas</div>
+ <h2 class="rail-title">Curated picks</h2>
+ <div class="rail" id="railCurated"></div>
+ </div>
</section>
<section class="section" id="shop">
@@ -498,7 +507,7 @@ const HOSTKEY = location.hostname.replace(/\./g, '_');
document.documentElement.dataset.view = state.view;
} catch(e){}
})();
-const LABELS = {"hand-block":"Hand block","handmade":"Handmade","hand-painted":"Hand painted","traditional":"Traditional Craft","teal":"Teal & Jewel Tones"};
+const LABELS = {"hand-block":"Hand block","handmade":"Handmade","hand-painted":"Hand painted"};
function escAttr(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[c])); }
// Image-URL allowlist: only DW Shopify CDN + designerwallcoverings.com (defends against XSS via crafted products.json)
@@ -1058,16 +1067,18 @@ loadGridPage();
});
})();
-// graphics-loop pass 12: hydrate Ideas rails from /api/sliders (tag-aware, shared rail-match)
+// graphics-loop pass 11: hydrate Ideas rails from /api/products
(async function hydrateIdeas() {
try {
- const container = document.getElementById('railsContainer');
- if (!container) return;
- const r = await fetch('/api/sliders');
+ const r = await fetch('/api/products?limit=80');
if (!r.ok) return;
const d = await r.json();
- const rails = (d.rails || []).filter(rail => rail.items && rail.items.length >= 4);
- if (!rails.length) { container.style.display = 'none'; return; }
+ const items = (d.items || []).filter(p => p && p.image_url);
+ if (!items.length) return;
+ const sorted = [...items].sort((a,b) => String(b.created_at || '').localeCompare(String(a.created_at || '')));
+ const newest = sorted.slice(0, 12);
+ // Curated = deterministic offset slice (every 5th item starting at idx 3) for variety
+ const curated = items.filter((_, i) => i % 5 === 3).slice(0, 12);
function card(p) {
const url = (p.image_url || '').replace(/(_\d+x\d*)(\.(jpg|jpeg|png|webp|gif))(\?|$)/i, '$2$4');
return '<a class="rail-card" href="/sample/' + encodeURIComponent(p.handle || p.sku) + '">' +
@@ -1076,14 +1087,10 @@ loadGridPage();
'<div class="rc-meta">Designer Wallcoverings</div>' +
'</a>';
}
- container.innerHTML = rails.map(rail => {
- const label = (typeof LABELS !== 'undefined' && LABELS[rail.key]) || rail.key.replace(/-/g, ' ');
- return '<div class="rail-block">'
- + '<div class="rail-eyebrow">Ideas</div>'
- + '<h2 class="rail-title">' + label + '</h2>'
- + '<div class="rail">' + rail.items.map(card).join('') + '</div>'
- + '</div>';
- }).join('');
+ const r1 = document.getElementById('railNewest');
+ const r2 = document.getElementById('railCurated');
+ if (r1) r1.innerHTML = newest.map(card).join('');
+ if (r2) r2.innerHTML = curated.map(card).join('');
} catch(e) {}
})();
</script>
diff --git a/server.js b/server.js
index 9ec6706..f9b319e 100644
--- a/server.js
+++ b/server.js
@@ -6,9 +6,6 @@ try { require('dotenv').config({ path: require('path').join(__dirname, '.env') }
const express = require('express');
const path = require('path');
const fs = require('fs');
-let buildRails, railFacets;
-try { ({ buildRails, railFacets } = require('../_shared/rail-match')); }
-catch (e) { buildRails = () => []; railFacets = () => ({}); }
const PORT = process.env.PORT || 9875;
const DW_SHOPIFY = 'https://designerwallcoverings.com';
@@ -43,7 +40,7 @@ let PRODUCTS = [];
let DROPPED = 0;
// graphics-loop pass 12: niche keyword filter — only show products that fit this site's niche
-const NICHE_POS = ["hand-painted","hand-screened","hand-printed","artisan","hand-finished","hand-embroidered","handmade","faux wood"];
+const NICHE_POS = ["hand-painted","hand-screened","hand-printed","artisan","hand-finished","hand-embroidered"];
const NICHE_NEG = ["solid","blank","plain"];
function nicheFit(p) {
const blob = ((p.title || '') + ' ' + (p.tags || []).join(' ')).toLowerCase();
@@ -192,13 +189,18 @@ app.get('/api/products', (req, res) => {
});
app.get('/api/sliders', (req, res) => {
- res.json({ rails: buildRails(PRODUCTS_NICHE, SITE_RAILS) });
+ const out = [];
+ for (const a of SITE_RAILS) {
+ const items = PRODUCTS_NICHE.filter(p => p.aesthetic === a).slice(0, 12);
+ if (items.length >= 4) out.push({ aesthetic: a, items });
+ }
+ res.json({ rails: out });
});
app.get('/api/facets', (req, res) => {
- const aesthetics = railFacets(PRODUCTS_NICHE, SITE_RAILS);
- const vendors = {};
+ const aesthetics = {}; const vendors = {};
for (const p of PRODUCTS_NICHE) {
+ aesthetics[p.aesthetic] = (aesthetics[p.aesthetic] || 0) + 1;
vendors[p.vendor] = (vendors[p.vendor] || 0) + 1;
}
res.json({ aesthetics, vendors, total: PRODUCTS_NICHE.length });
diff --git a/site.config.json b/site.config.json
index e89471c..e5c61bc 100644
--- a/site.config.json
+++ b/site.config.json
@@ -10,8 +10,12 @@
"accent": "#a07050"
},
"rails": [
- "traditional",
- "teal"
+ "hand-printed",
+ "hand-painted",
+ "artisan",
+ "small-batch",
+ "custom",
+ "heritage"
],
"port": 9897
}
← d98385d rails: tag-aware via shared rail-match helper + editorial LA
·
back to Handcraftedwallpaper
·
sku-redact: wire shared vendor-id display scrubber 8216d67 →