← back to Designer Wallcoverings
Diagnose + stage revert of broken Approach-B section-inside-section on LIVE collection page
de52ba2c94fb9cd40e6fe91c3325cc48a1d4200a · 2026-06-23 07:32:01 -0700 · Steve Abrams
Live main theme 142250278963 (Steves Version 5.0) sections/collection.liquid L85
had {%- section 'collection-filters-horizontal' -%} inside the collection section
-> 'Cannot render sections inside sections' on every collection page. Prior fix
commits targeted the wrong (now-unpublished) theme 143739584563. Adds race-safe
push-revert-collection-fix.sh (Steve-gated live push) + original backup + fixed file.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A shopify/proposed-fixes/sections__collection.liquid.MAIN-142250278963.FIXED.liquidA shopify/push-revert-collection-fix.sh
Diff
commit de52ba2c94fb9cd40e6fe91c3325cc48a1d4200a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 23 07:32:01 2026 -0700
Diagnose + stage revert of broken Approach-B section-inside-section on LIVE collection page
Live main theme 142250278963 (Steves Version 5.0) sections/collection.liquid L85
had {%- section 'collection-filters-horizontal' -%} inside the collection section
-> 'Cannot render sections inside sections' on every collection page. Prior fix
commits targeted the wrong (now-unpublished) theme 143739584563. Adds race-safe
push-revert-collection-fix.sh (Steve-gated live push) + original backup + fixed file.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
...ollection.liquid.MAIN-142250278963.FIXED.liquid | 256 +++++++++++++++++++++
shopify/push-revert-collection-fix.sh | 74 ++++++
2 files changed, 330 insertions(+)
diff --git a/shopify/proposed-fixes/sections__collection.liquid.MAIN-142250278963.FIXED.liquid b/shopify/proposed-fixes/sections__collection.liquid.MAIN-142250278963.FIXED.liquid
new file mode 100644
index 00000000..323baf20
--- /dev/null
+++ b/shopify/proposed-fixes/sections__collection.liquid.MAIN-142250278963.FIXED.liquid
@@ -0,0 +1,256 @@
+<script
+ type="application/json"
+ data-section-id="{{ section.id }}"
+ data-section-type="static-collection"
+>
+</script>
+
+{% liquid
+ assign products_per_page = section.settings.products_per_row | times: section.settings.number_of_rows
+ assign use_masonry = false
+
+ if section.settings.layout == 'masonry'
+ assign use_masonry = true
+ endif
+
+ assign show_filters = false
+ if section.settings.show_filters
+ assign show_filters = true
+ endif
+
+ assign show_sorting = false
+ if section.settings.sorting
+ assign show_sorting = true
+ endif
+
+ assign show_collection_image = false
+ if collection.image and section.settings.show_collection_image
+ assign show_collection_image = true
+ endif
+%}
+
+<div>
+ {% unless use_masonry %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% render 'breadcrumbs' %}
+ {% endunless %}
+
+ {% paginate collection.products by products_per_page %}
+ <section
+ class="collection collection-image--{{ show_collection_image }}"
+ data-product-hover="{{ settings.product_hover }}"
+ {% if use_masonry %}data-collection-masonry{% endif %}
+ data-section-id="{{ section.id }}"
+ data-section-type="collection">
+
+ {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
+ <div
+ class="
+ collection-header
+ {% if use_masonry %}
+ collection-header-alternate
+ {% endif %}
+ {% if show_filters and show_sorting %}
+ collection-header--filters-sort-enabled
+ {% endif %}
+ "
+ >
+ {% if show_collection_image %}
+ <div class="collection-featured-image">
+ {%
+ render 'rimg',
+ img: collection.image,
+ size: '1024x1024',
+ lazy: true,
+ %}
+ </div>
+ {% endif %}
+
+ <div class="collection-header-content">
+ {% if use_masonry %}
+ {% render 'breadcrumbs' %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% endif %}
+
+ {% if collection.description != blank and section.settings.show_description %}
+ <div class="collection-description rte">
+ {{ collection.description }}
+ </div>
+ {% endif %}
+
+ {% if show_filters or show_sorting %}
+ <div class="collection-filters">
+ {% if show_filters and collection.filters.size > 0 %}
+ <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
+ <div class="faceted-filters" data-faceted-filter>
+ {%
+ render "faceted-filters",
+ filters: collection.filters,
+ class_prefix: 'collection',
+ %}
+ </div>
+ {% endif %}
+ {% if show_sorting %}
+ <div class="collection-sorting__wrapper">
+ <label class="collection-filters__title label" for="sort-by">
+ {{- 'collections.collection.sort_title' | t -}}:
+ </label>
+
+ <div
+ class="
+ collection-dropdown
+ collection-dropdown--sort
+ select-wrapper
+ {% if collection.current_vendor %}
+ vendor-collection
+ {% endif %}
+ "
+ >
+ {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+
+ <span class="selected-text"></span>
+
+ <select id="sort-by" class="select" data-collection-sorting>
+ {%- for option in collection.sort_options -%}
+ {% if current_sort == option.value %}
+ <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
+ {% else %}
+ <option value="{{ option.value }}">{{ option.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ {% endif %}
+ </div>
+
+ {% if show_filters and collection.filters.size > 0 %}
+ {% for filter in collection.filters %}
+ {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
+ {%-
+ render 'faceted-filters-active',
+ show_sorting: show_sorting,
+ filter: filter,
+ filters: collection.filters,
+ class_prefix: 'collection',
+ clear_url: collection.url,
+ %}
+ {% break %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </div>
+ {% endif %}
+
+ <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
+ {% include 'collection-toolbar' %}
+
+ <div
+ class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
+ data-collection-grid
+ {% if use_masonry %}data-masonry-grid{% endif %}
+ >
+ {%- if use_masonry -%}
+ <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
+ {%- endif -%}
+
+ {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
+ {%- for i in (1..section.settings.products_per_row) -%}
+ {%- capture productImage -%}
+ {%- cycle 'product-1', 'product-2', 'product-3' -%}
+ {%- endcapture -%}
+ {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+
+ {%- render 'home-onboard-product', image: image -%}
+ {%- endfor -%}
+ {%- else -%}
+ {% for product in collection.products %}
+ {%
+ render 'product-list-item',
+ product: product,
+ %}
+ {% else %}
+ {% capture continueLink %}
+ <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
+ {% endcapture %}
+ <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
+ {% endfor %}
+ {%- endif -%}
+ </div>
+ </section>
+
+ {%
+ render 'pagination',
+ paginate: paginate,
+ %}
+ {% endpaginate %}
+</div>
+
+<script src="{{ 'collection-grid-density.js' | asset_url }}" defer></script>
+
+{% schema %}
+{
+ "name": "Collection pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_collection_image",
+ "label": "Show collection image"
+ },
+ {
+ "type": "checkbox",
+ "id": "show_description",
+ "label": "Show description"
+ },
+ {
+ "type": "checkbox",
+ "id": "sorting",
+ "label": "Enable sorting",
+ "info": "Parameters include: best selling, A-Z, newest to oldest, etc."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_filters",
+ "label": "Enable filtering",
+ "default": true
+ },
+ {
+ "type": "select",
+ "id": "layout",
+ "label": "Layout",
+ "options": [
+ {
+ "value": "default",
+ "label": "Default"
+ },
+ {
+ "value": "masonry",
+ "label": "Masonry"
+ }
+ ],
+ "default": "default"
+ },
+ {
+ "type": "range",
+ "id": "products_per_row",
+ "label": "Products per row",
+ "min": 2,
+ "max": 4,
+ "step": 1,
+ "default": 3
+ },
+ {
+ "type": "range",
+ "id": "number_of_rows",
+ "label": "Rows",
+ "min": 1,
+ "max": 12,
+ "step": 1,
+ "default": 3
+ }
+ ]
+}
+
+{% endschema %}
diff --git a/shopify/push-revert-collection-fix.sh b/shopify/push-revert-collection-fix.sh
new file mode 100755
index 00000000..750798bf
--- /dev/null
+++ b/shopify/push-revert-collection-fix.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+# REVERT the broken "Approach B" horizontal-filter element from the LIVE collection page.
+#
+# Bug: sections/collection.liquid had `{%- section 'collection-filters-horizontal' -%}`
+# rendered INSIDE the collection section → Shopify error on every collection page:
+# "Liquid error (sections/collection line 85): Cannot render sections inside sections"
+#
+# Why it slipped through: the other "Fix" commits pushed to theme 143739584563
+# ("NewWall Template [Dev]", now UNPUBLISHED). The actual LIVE/main theme is
+# 142250278963 "Steves Version 5.0" — it never got the fix.
+#
+# This script is RACE-SAFE: it pulls the CURRENT live asset, surgically removes only
+# the offending block, backs up the original, PUTs, and verifies the error is gone.
+# It keeps the native Boost faceted-filters (the original working filter UI).
+#
+# bash push-revert-collection-fix.sh
+set -euo pipefail
+cd "$(dirname "$0")"
+
+STORE="designer-laboratory-sandbox.myshopify.com"
+API="2024-10"
+MAIN="142250278963" # role=main / published — "Steves Version 5.0"
+SECRETS="$HOME/Projects/secrets-manager/.env"
+TOK="${THEME_TOKEN:-$(grep -hE '^SHOPIFY_THEME_TOKEN=' "$SECRETS" 2>/dev/null | head -1 | cut -d= -f2- | tr -d '"'"'"' ')}"
+[ -z "$TOK" ] && { echo "No theme token. Run: THEME_TOKEN=shpat_xxx bash $0"; exit 1; }
+echo "token …${TOK: -4} | LIVE main theme $MAIN"
+mkdir -p theme-backups
+
+python3 - "$STORE" "$API" "$TOK" "$MAIN" <<'PY'
+import sys, json, urllib.request, urllib.parse, datetime, re
+store, api, tok, tid = sys.argv[1:5]
+H = {"X-Shopify-Access-Token": tok, "Content-Type": "application/json"}
+key = "sections/collection.liquid"
+url = f"https://{store}/admin/api/{api}/themes/{tid}/assets.json?" + urllib.parse.urlencode({"asset[key]": key})
+
+a = json.load(urllib.request.urlopen(urllib.request.Request(url, headers=H)))["asset"]
+src = a["value"]
+print(f"pulled fresh: {len(src)} bytes, updated {a['updated_at']}")
+lines = src.split("\n")
+idx = [i for i,l in enumerate(lines) if re.search(r"{%-?\s*section\s+'collection-filters-horizontal'", l)]
+if not idx:
+ print("Already clean — no Approach-B section call. Nothing to do."); sys.exit(0)
+i = idx[0]
+drop = {i}
+if i-1>=0 and "Approach B" in lines[i-1]: drop.add(i-1)
+if i+1<len(lines) and lines[i+1].strip()=="": drop.add(i+1)
+new_lines = [l for j,l in enumerate(lines) if j not in drop]
+new = "\n".join(new_lines)
+remain = [n+1 for n,l in enumerate(new_lines) if re.search(r"{%-?\s*section\s", l)]
+if remain:
+ print(f"ABORT: other {{% section %}} calls remain at {remain} — manual review."); sys.exit(4)
+print("removing:")
+for j in sorted(drop): print(f" -{j+1}| {lines[j]}")
+
+stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
+bk = f"theme-backups/sections__collection.liquid.MAIN-{tid}.{stamp}.bak"; open(bk,"w").write(src)
+print("backup:", bk)
+
+body = json.dumps({"asset": {"key": key, "value": new}}).encode()
+r = urllib.request.urlopen(urllib.request.Request(
+ f"https://{store}/admin/api/{api}/themes/{tid}/assets.json", data=body, method="PUT", headers=H))
+print(f"PUT HTTP {r.status} OK -> {len(new)} bytes on LIVE main {tid}")
+
+chk = json.load(urllib.request.urlopen(urllib.request.Request(url, headers=H)))["asset"]["value"]
+print("verify asset clean:", not re.search(r"{%-?\s*section\s+'collection-filters-horizontal'", chk))
+PY
+
+echo "=== verify live page (fresh render) ==="
+sleep 3
+for c in phyllis-morris-classic-wallcovering animal-skin all; do
+ err=$(curl -sS -A "Mozilla/5.0" "https://www.designerwallcoverings.com/collections/$c?_cb=$(date +%s)" | grep -oE "Liquid error \(sections/collection line [0-9]+\)[^<]*" | head -1)
+ printf " %-38s %s\n" "$c" "${err:-OK (no liquid error)}"
+done
+echo "Done. To roll back: PUT the newest theme-backups/sections__collection.liquid.MAIN-${MAIN}.*.bak back to theme ${MAIN}."
← bfe782d2 Upgrade all Gemini text calls from deprecated gemini-2.0-fla
·
back to Designer Wallcoverings
·
Deploy collection toolbar to live theme: sort dropdown + gri d3069393 →