← back to Designer Wallcoverings
Add infinite-scroll replicator (copies NewWall lock + newwall-infinite.js wiring between dev themes)
962629d46a131ad3c1dbd7259ecb8056a20ca62e · 2026-06-21 20:14:31 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
A shopify/push-infinite-scroll-to-dev-theme.sh
Diff
commit 962629d46a131ad3c1dbd7259ecb8056a20ca62e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jun 21 20:14:31 2026 -0700
Add infinite-scroll replicator (copies NewWall lock + newwall-infinite.js wiring between dev themes)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
shopify/push-infinite-scroll-to-dev-theme.sh | 68 ++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/shopify/push-infinite-scroll-to-dev-theme.sh b/shopify/push-infinite-scroll-to-dev-theme.sh
new file mode 100644
index 00000000..db7e5b47
--- /dev/null
+++ b/shopify/push-infinite-scroll-to-dev-theme.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+# Replicate the working NewWall infinite-scroll wiring from the source theme
+# "NewWall Template [Dev]" (143739584563) into the target dev theme
+# "Updated copy of NewWall Template [Dev]" (143794536499).
+#
+# The target already HAS assets/newwall-infinite.js (identical) but its
+# theme.liquid never loads it, and lacks the inline paginationType-lock that
+# forces Boost infinite scroll over the theme's stale "default" config.
+# This copies BOTH the inline lock block and the <script> include. Drift-safe,
+# idempotent, backup+verify. Never touches the live/main theme.
+#
+# THEME_TOKEN=shpat_xxx bash push-infinite-scroll-to-dev-theme.sh
+set -euo pipefail
+cd "$(dirname "$0")"
+STORE="designer-laboratory-sandbox.myshopify.com"; API="2024-10"
+SRC_THEME=143739584563 # working
+TGT_THEME=143794536499 # target
+TOK="${THEME_TOKEN:?set THEME_TOKEN}"
+
+python3 - "$STORE" "$API" "$TOK" "$SRC_THEME" "$TGT_THEME" "theme-backups" <<'PY'
+import sys,json,re,urllib.request,urllib.parse,datetime
+store,api,tok,src_t,tgt_t,bkdir=sys.argv[1:7]
+H={"X-Shopify-Access-Token":tok,"Content-Type":"application/json"}
+def aurl(tid,key): return f"https://{store}/admin/api/{api}/themes/{tid}/assets.json?"+urllib.parse.urlencode({"asset[key]":key})
+def get(tid,key): return json.load(urllib.request.urlopen(urllib.request.Request(aurl(tid,key),headers=H)))["asset"]["value"]
+
+src=get(src_t,"layout/theme.liquid").splitlines()
+# inline lock block: comment marker -> first </script> after it
+s=next(i for i,l in enumerate(src) if "NewWall: force Boost infinite scroll" in l)
+e=next(i for i in range(s,len(src)) if "</script>" in src[i])
+INLINE="\n".join(src[s:e+1])
+INCLUDE="""<script src="{{ 'newwall-infinite.js' | asset_url }}" defer></script>"""
+print(f"extracted inline lock ({e-s+1} lines, {len(INLINE)} bytes) + include")
+
+tgt=get(tgt_t,"layout/theme.liquid")
+orig=tgt
+# backup
+stamp=datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
+bk=f"{bkdir}/theme.liquid.dev-{tgt_t}.{stamp}.infinite.bak"
+open(bk,"w").write(tgt); print("backup:",bk,f"({len(tgt)} bytes)")
+
+changes=[]
+# 1. inline lock — insert after X-UA-Compatible meta (matches source placement), idempotent
+if "NewWall: force Boost infinite scroll" not in tgt:
+ m=re.search(r'(<meta http-equiv="X-UA-Compatible"[^>]*>\s*\n)', tgt)
+ if not m: m=re.search(r'(<meta charset="utf-8">\s*\n)', tgt)
+ if m:
+ tgt=tgt[:m.end()]+"\n"+INLINE+"\n"+tgt[m.end():]; changes.append("inline-lock")
+ else:
+ tgt=tgt.replace("</head>", INLINE+"\n</head>",1); changes.append("inline-lock@head")
+# 2. include — before </head>, idempotent
+if "newwall-infinite.js" not in tgt:
+ tgt=tgt.replace("</head>", " "+INCLUDE+"\n</head>",1); changes.append("include")
+
+print("changes:", ", ".join(changes) or "none (already wired)")
+if tgt==orig: print("nothing to do."); sys.exit(0)
+
+body=json.dumps({"asset":{"key":"layout/theme.liquid","value":tgt}}).encode()
+try:
+ r=urllib.request.urlopen(urllib.request.Request(f"https://{store}/admin/api/{api}/themes/{tgt_t}/assets.json",data=body,method="PUT",headers=H))
+ print("PUT HTTP",r.status,"OK",f"({len(tgt)} bytes)")
+except urllib.error.HTTPError as ex:
+ print("PUT FAILED",ex.code,ex.read().decode()[:200]); sys.exit(1)
+ver=get(tgt_t,"layout/theme.liquid")
+print("verify: inline-lock:", "force Boost infinite scroll" in ver, "| include:", "newwall-infinite.js" in ver)
+print(f"PREVIEW: https://www.designerwallcoverings.com/collections/new-arrivals?preview_theme_id={tgt_t}")
+print(f"revert: PUT {bk} back to layout/theme.liquid on theme {tgt_t}")
+PY
← 7f24f962 auto-save: 2026-06-21T20:01:45 (1 files) — shopify/scripts/d
·
back to Designer Wallcoverings
·
auto-save: 2026-06-22T01:03:04 (3 files) — shopify/scripts/c 6cf19be1 →