diff --git a/bp/product/routes.py b/bp/product/routes.py index 799a365..ca230c8 100644 --- a/bp/product/routes.py +++ b/bp/product/routes.py @@ -22,20 +22,12 @@ from .services.product_operations import toggle_product_like, massage_full_produ def register(): - bp = Blueprint("product", __name__, url_prefix="/product/") + bp = Blueprint("product", __name__, url_prefix="/product/") @bp.url_value_preprocessor - def pull_blog(endpoint, values): - # App-level preprocessor pops both "slug" and "page_slug" into g.post_slug, - # with page_slug overwriting slug. We need the original product slug which - # the app preprocessor popped first — but it's gone. Instead, extract the - # product slug from the request path: .../product//... - from quart import request as req - parts = req.path.rstrip("/").split("/") - try: - idx = parts.index("product") - g.product_slug = parts[idx + 1] if idx + 1 < len(parts) else None - except (ValueError, IndexError): - g.product_slug = None + def pull_product_slug(endpoint, values): + # product_slug is distinct from the app-level "slug"/"page_slug" params, + # so it won't be popped by the app-level preprocessor in app.py. + g.product_slug = values.pop("product_slug", None) # ───────────────────────────────────────────────────────────── # BEFORE REQUEST: Slug or numeric ID resolver @@ -71,7 +63,7 @@ def register(): if not is_post: canon = canonical_html_slug(product["slug"]) return redirect( - host_url(url_for("market.browse.product.product_detail", slug=canon)) + host_url(url_for("market.browse.product.product_detail", product_slug=canon)) ) g.item_data = {"d": product, "slug": product["slug"], "liked": False} @@ -84,7 +76,7 @@ def register(): canon = canonical_html_slug(raw_slug) if canon != raw_slug and not is_post: return redirect( - host_url(url_for("market.browse.product.product_detail", slug=canon)) + host_url(url_for("market.browse.product.product_detail", product_slug=canon)) ) # hydrate full product @@ -111,7 +103,7 @@ def register(): # ───────────────────────────────────────────────────────────── @bp.get("/") @cache_page(tag="browse") - async def product_detail(slug: str): + async def product_detail(): from shared.browser.app.utils.htmx import is_htmx_request # Determine which template to use based on request type @@ -126,9 +118,8 @@ def register(): @bp.post("/like/toggle/") @clear_cache(tag="browse", tag_scope="user") - async def like_toggle(slug): - # Use slug from URL parameter (set by url_prefix="/product/") - product_slug = slug + async def like_toggle(): + product_slug = g.product_slug if not g.user: html = await render_template( @@ -157,7 +148,7 @@ def register(): @bp.get("/admin/") - async def admin(slug: str): + async def admin(): from shared.browser.app.utils.htmx import is_htmx_request if not is_htmx_request(): @@ -177,7 +168,7 @@ def register(): @bp.post("/cart/") @clear_cache(tag="browse", tag_scope="user") - async def cart(**_kw): + async def cart(): slug = g.product_slug # make sure product exists (we *allow* deleted_at != None later if you want) product_id = await g.s.scalar( diff --git a/shared b/shared index 2a9dfaa..0d40dfa 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 2a9dfaa749be414903b5edf834fbb201e6466498 +Subproject commit 0d40dfaeca7dbdc8adeaf7b071bfd9faccb74511 diff --git a/templates/_types/product/_cart.html b/templates/_types/product/_cart.html index 98779d1..2c68284 100644 --- a/templates/_types/product/_cart.html +++ b/templates/_types/product/_cart.html @@ -7,9 +7,9 @@ {% if not quantity %}
@@ -80,9 +80,9 @@ @@ -139,7 +139,7 @@

- {% set href=url_for('market.browse.product.product_detail', slug=p.slug) %} + {% set href=url_for('market.browse.product.product_detail', product_slug=p.slug) %} Quantity @@ -212,9 +212,9 @@ {{ item.quantity }}