diff --git a/docs/tickets/mps-24.md b/docs/tickets/mps-24.md index d774136..063d1f7 100644 --- a/docs/tickets/mps-24.md +++ b/docs/tickets/mps-24.md @@ -363,6 +363,19 @@ Tests (`test_functional.py::TestProductTagsSpa`): Deferred (occasional click, not the hot path): AJAX-ifying the "Suggest categories" link — still a full navigation by design. +**Phase 2.8i — chip strip on every SERP page** (shipped 2026-05-16): +operator: "leave the chits on screen for all serp pages." The +horizontal `tag-chip-strip` rendered only on the shop home; drilling +into a category (tag-detail SERP `shop_tag.j2`) dropped it, so hopping +categories meant going back. Extracted the (duplicated) chip strip +from `home.j2`/`shop.j2` into a single `_facet_nav.j2` `chip_strip(...)` +macro and added it to `shop_tag.j2` under the header. The +`shop_tag_detail` view already supplied `home_chips` / `active_tag` / +sort / price, so this was a template-only gap; the active category +chip highlights on the SERP and carries `facet_qs`. Search SERP +already renders `home.j2` so it gets the macro for free. Test: +`test_chip_strip_stays_on_tag_detail_serp`. + **Phase 2.8h — facets compose, not clobber** (shipped 2026-05-16): operator: "switching one breaks it" — picking a category reset the active Sort + Price. Cause: the facet category links / "All" link / diff --git a/make_post_sell/templates/_facet_nav.j2 b/make_post_sell/templates/_facet_nav.j2 index 004eab8..98102a1 100644 --- a/make_post_sell/templates/_facet_nav.j2 +++ b/make_post_sell/templates/_facet_nav.j2 @@ -118,3 +118,22 @@ {{ facet_form(base_url, tag_base, sort_options, sort_key, price_min, price_max, facet_tags, active_tag) }} {% endmacro %} + +{# Horizontal category chip strip. Single source of truth — used by the + shop home (home.j2 / shop.j2) AND every SERP page (shop_tag.j2) so + the chips stay on screen as the shopper hops categories. Carries the + active sort/price (facet_qs) so switching category composes. #} +{% macro chip_strip(shop_url, tag_base, home_chips, active_tag, sort_key, price_min, price_max) %} +{% if home_chips %} + +{% endif %} +{% endmacro %} diff --git a/make_post_sell/templates/home.j2 b/make_post_sell/templates/home.j2 index 0422b72..b0e5766 100644 --- a/make_post_sell/templates/home.j2 +++ b/make_post_sell/templates/home.j2 @@ -88,24 +88,11 @@ Layout 0 (flat) keeps its existing simple grid with no nav. #} {% set show_facet_nav = request.shop.home_layout and request.shop.home_layout >= 1 %} - {# MPS-24: tag chip strip — shown on layout 1 (chips) and 2 (lanes). - Chips and the facet left-nav point at the SAME targets (shop home - for "All", {tag_base}/tag/{slug} per category) so the two stay in - lock-step. tag_filter.js keeps full navigation for /tag/ hrefs. #} - {% if home_chips %} - - {% endif %} + {# MPS-24: tag chip strip — shared macro, shown on layout 1 (chips) + and 2 (lanes) AND every SERP page (shop_tag.j2). Chips + facet + left-nav hit the SAME targets; tag_filter.js keeps full navigation + for /tag/ hrefs. #} + {{ facet.chip_strip(shop_url, tag_base, home_chips, active_tag, sort_key, price_min, price_max) }} {% if show_facet_nav %} {# Mobile/tablet: collapsed
facets above the grid. #} diff --git a/make_post_sell/templates/shop.j2 b/make_post_sell/templates/shop.j2 index db01a8b..d19828b 100644 --- a/make_post_sell/templates/shop.j2 +++ b/make_post_sell/templates/shop.j2 @@ -15,27 +15,12 @@ {% set tag_base = request.shop.absolute_url(request, slug=False) %} {% set show_facet_nav = request.shop.home_layout and request.shop.home_layout >= 1 %} -{# MPS-24: tag chip strip — shown on layout 1 (chips) and 2 (lanes). #} -{# Chip strip and the facet left-nav point at the SAME targets: the - shop home for "All" and the canonical tag detail page - ({tag_base}/tag/{slug}) per category. tag_filter.js detects the - /tag/ href and keeps full navigation, so a chip and its matching - sidebar entry always land on the same page with the same active - state. #} -{% if home_chips %} - -{% endif %} +{# MPS-24: tag chip strip — shared macro (single source of truth), + shown on layout 1 (chips) and 2 (lanes) AND every SERP page. Chip + strip + facet left-nav point at the SAME targets; tag_filter.js + keeps full navigation for /tag/ hrefs so a chip and its sidebar + entry land on the same SERP with the same active state. #} +{{ facet.chip_strip(shop_url, tag_base, home_chips, active_tag, sort_key, price_min, price_max) }} {% if show_facet_nav %} {# Mobile/tablet: collapsed
facets above the grid. #} diff --git a/make_post_sell/templates/shop_tag.j2 b/make_post_sell/templates/shop_tag.j2 index 6c0562a..f1783a1 100644 --- a/make_post_sell/templates/shop_tag.j2 +++ b/make_post_sell/templates/shop_tag.j2 @@ -11,6 +11,11 @@

← All products

+{# Chip strip stays on screen on every SERP page so the shopper can + hop categories without going back. Same shared macro as the shop + home; active_tag highlights the current category. #} +{{ facet.chip_strip(shop_url, tag_base, home_chips, active_tag, sort_key, price_min, price_max) }} + {# Mobile/tablet: collapsed
facets above the grid (CSS hides it ≥800px where the sidebar takes over). #} {{ facet.details(shop_url, tag_base, sort_options, sort_key, price_min, price_max, facet_tags, active_tag) }} diff --git a/make_post_sell/tests/test_functional.py b/make_post_sell/tests/test_functional.py index 1626c62..b257c54 100644 --- a/make_post_sell/tests/test_functional.py +++ b/make_post_sell/tests/test_functional.py @@ -8947,6 +8947,43 @@ class TestHomeLayoutAndTags(_AuthenticatedBase): self.assertIn('tag-detail-header', body) self.assertIn('serp-list', body) + def test_chip_strip_stays_on_tag_detail_serp(self): + """Operator: 'leave the chits on screen for all serp pages.' + The horizontal chip strip must render on the tag-detail SERP + (not just the shop home) so the shopper can hop categories + without going back. The current category chip is active.""" + shop, product = self._make_shop_with_product("chip-serp-shop") + self.testapp.post( + f"/s/{shop.id}/settings", + { + "form_section": "home-layout-settings", + "home_layout": "2", + "home_layout_tag_limit": "5", + "home_layout_per_lane_limit": "10", + "submit": "Save Home Layout", + }, + ) + self.testapp.post( + f"/p/{product.id}/edit", + { + "title": product.title, + "description": "One. Two. Three. Four. Five. Six.", + "price": str(product.price), + "visibility": "1", + "tags": "Math", + }, + ) + res = self.testapp.get(f"/s/{shop.id}/tag/math") + body = res.body.decode() + # The shared chip strip is present on the SERP page. + self.assertIn('class="tag-chip-strip"', body) + self.assertIn('data-tag-strip', body) + # The active category chip is highlighted on the SERP. + self.assertIn('tag-chip tag-chip-active', body) + # And it still has the facet sidebar (chip strip is additive, + # not a replacement). + self.assertIn('facet-nav', body) + def test_facet_links_preserve_sort_and_price(self): """Operator report: 'switching one breaks it' — changing category reset sort/price. Every category link / All link / chip / lane