← back to Madagascarwallpaper
graphic-loop pass 12: niche keyword filter (no off-niche products like 'solid' on patterned sites)
be4dd34488c541685b51a82d76fd9f0daef723ed · 2026-05-07 13:19:46 -0700 · Steve
Files touched
Diff
commit be4dd34488c541685b51a82d76fd9f0daef723ed
Author: Steve <steve@designerwallcoverings.com>
Date: Thu May 7 13:19:46 2026 -0700
graphic-loop pass 12: niche keyword filter (no off-niche products like 'solid' on patterned sites)
---
server.js | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/server.js b/server.js
index 7f9a85a..e2ff823 100644
--- a/server.js
+++ b/server.js
@@ -36,6 +36,22 @@ const PRODUCTS = DATA_RAW.filter(p => !isJunk(p));
const DROPPED = DATA_RAW.length - PRODUCTS.length;
console.log(`Loaded ${DATA_RAW.length}, kept ${PRODUCTS.length}, dropped ${DROPPED}`);
+// graphics-loop pass 12: niche keyword filter — only show products that fit this site's niche
+const NICHE_POS = ["raffia","palm","tropical","natural fiber","grasscloth","jungle"];
+const NICHE_NEG = ["solid","blank","plain"];
+function nicheFit(p) {
+ const blob = ((p.title || '') + ' ' + (p.tags || []).join(' ')).toLowerCase();
+ if (NICHE_NEG.some(n => blob.includes(n.toLowerCase()))) return false;
+ return NICHE_POS.length === 0 || NICHE_POS.some(k => blob.includes(k.toLowerCase()));
+}
+const PRODUCTS_NICHE = PRODUCTS.filter(nicheFit);
+const NICHE_DROPPED = PRODUCTS.length - PRODUCTS_NICHE.length;
+console.log(`Niche filter: kept ${PRODUCTS_NICHE.length} of ${PRODUCTS.length}, dropped ${NICHE_DROPPED}`);
+// Replace PRODUCTS reference with the niche-filtered list for all downstream handlers.
+const PRODUCTS_ORIG = PRODUCTS;
+Object.defineProperty(global, '__products_niche_applied', { value: true });
+
+
const app = express();
// DW STANDARD: sort by color/style/sku/title for any product-rendering site.
const COLOR_RANK = {
@@ -76,7 +92,7 @@ app.use(express.static(path.join(__dirname, 'public')));
app.get('/api/products', (req, res) => {
const { q, aesthetic, vendor, page = 1, limit = 24, sort = 'newest'} = req.query;
- let list = PRODUCTS;
+ let list = PRODUCTS_NICHE;
if (q) {
const needle = q.toLowerCase();
list = list.filter(p => (p.title || '').toLowerCase().includes(needle) || (p.tags || []).some(t => t.toLowerCase().includes(needle)));
@@ -96,7 +112,7 @@ app.get('/api/sliders', (req, res) => {
const SLIDER_AESTHETICS = ["raffia","tropical","natural","woven","botanical","jute"];
const out = [];
for (const a of SLIDER_AESTHETICS) {
- const items = PRODUCTS.filter(p => p.aesthetic === a).slice(0, 12);
+ 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 });
@@ -104,17 +120,17 @@ app.get('/api/sliders', (req, res) => {
app.get('/api/facets', (req, res) => {
const aesthetics = {}; const vendors = {};
- for (const p of PRODUCTS) {
+ 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.length });
});
-app.get('/api/health', (req, res) => res.json({ status: 'ok', count: PRODUCTS.length, dropped: DROPPED }));
+app.get('/api/health', (req, res) => res.json({ status: 'ok', count: PRODUCTS_NICHE.length, dropped: DROPPED }));
app.get('/sample/:handle', (req, res) => {
- const p = PRODUCTS.find(x => x.handle === req.params.handle || x.sku === req.params.handle);
+ const p = PRODUCTS_NICHE.find(x => x.handle === req.params.handle || x.sku === req.params.handle);
if (!p) return res.status(404).send('Not found');
res.redirect(302, p.product_url || `${DW_SHOPIFY}/products/${encodeURIComponent(p.handle)}#sample`);
});
← cb3d7ec graphic-loop pass 11: add Ideas rails (New this week + Curat
·
back to Madagascarwallpaper
·
graphic-loop pass 13: real footer brand + Facebook link + OG ce3175d →