Add market_product_url helper for correct product URLs
market_url('/product/...') was missing the /<page_slug>/<market_slug>/
prefix required by the market app's route structure. New helper
market_product_url() resolves the prefix from request context
(g.post_slug/g.market_slug in market app, g.page_slug + market_place
in cart app).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<ul class="divide-y divide-stone-100 text-xs sm:text-sm">
|
<ul class="divide-y divide-stone-100 text-xs sm:text-sm">
|
||||||
{% for item in order.items %}
|
{% for item in order.items %}
|
||||||
<li>
|
<li>
|
||||||
<a class="w-full py-2 flex gap-3" href="{{ market_url('/product/' + item.product.slug + '/') }}">
|
<a class="w-full py-2 flex gap-3" href="{{ market_product_url(item.product.slug) }}">
|
||||||
{# Thumbnail #}
|
{# Thumbnail #}
|
||||||
<div class="w-12 h-12 sm:w-14 sm:h-14 rounded-md bg-stone-100 flex-shrink-0 overflow-hidden">
|
<div class="w-12 h-12 sm:w-14 sm:h-14 rounded-md bg-stone-100 flex-shrink-0 overflow-hidden">
|
||||||
{% if item.product and item.product.image %}
|
{% if item.product and item.product.image %}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
{% if not quantity %}
|
{% if not quantity %}
|
||||||
<form
|
<form
|
||||||
action="{{ market_url('/product/' + slug + '/cart') }}"
|
action="{{ market_product_url(slug, 'cart') }}"
|
||||||
method="post"
|
method="post"
|
||||||
hx-post="{{ market_url('/product/' + slug + '/cart') }}"
|
hx-post="{{ market_product_url(slug, 'cart') }}"
|
||||||
hx-target="#cart-mini"
|
hx-target="#cart-mini"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
class="rounded flex items-center"
|
class="rounded flex items-center"
|
||||||
@@ -38,9 +38,9 @@
|
|||||||
<div class="rounded flex items-center gap-2">
|
<div class="rounded flex items-center gap-2">
|
||||||
<!-- minus -->
|
<!-- minus -->
|
||||||
<form
|
<form
|
||||||
action="{{ market_url('/product/' + slug + '/cart') }}"
|
action="{{ market_product_url(slug, 'cart') }}"
|
||||||
method="post"
|
method="post"
|
||||||
hx-post="{{ market_url('/product/' + slug + '/cart') }}"
|
hx-post="{{ market_product_url(slug, 'cart') }}"
|
||||||
hx-target="#cart-mini"
|
hx-target="#cart-mini"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
@@ -80,9 +80,9 @@
|
|||||||
|
|
||||||
<!-- plus -->
|
<!-- plus -->
|
||||||
<form
|
<form
|
||||||
action="{{ market_url('/product/' + slug + '/cart') }}"
|
action="{{ market_product_url(slug, 'cart') }}"
|
||||||
method="post"
|
method="post"
|
||||||
hx-post="{{ market_url('/product/' + slug + '/cart') }}"
|
hx-post="{{ market_product_url(slug, 'cart') }}"
|
||||||
hx-target="#cart-mini"
|
hx-target="#cart-mini"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
<div class="flex flex-col sm:flex-row sm:items-start justify-between gap-2 sm:gap-3">
|
<div class="flex flex-col sm:flex-row sm:items-start justify-between gap-2 sm:gap-3">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<h2 class="text-sm sm:text-base md:text-lg font-semibold text-stone-900">
|
<h2 class="text-sm sm:text-base md:text-lg font-semibold text-stone-900">
|
||||||
{% set href=market_url('/product/' + p.slug + '/') %}
|
{% set href=market_product_url(p.slug, market_place=item.market_place) %}
|
||||||
<a
|
<a
|
||||||
href="{{ href }}"
|
href="{{ href }}"
|
||||||
hx_get="{{href}}"
|
hx_get="{{href}}"
|
||||||
@@ -189,9 +189,9 @@
|
|||||||
<div class="flex items-center gap-2 text-xs sm:text-sm text-stone-700">
|
<div class="flex items-center gap-2 text-xs sm:text-sm text-stone-700">
|
||||||
<span class="text-[0.65rem] sm:text-xs uppercase tracking-wide text-stone-500">Quantity</span>
|
<span class="text-[0.65rem] sm:text-xs uppercase tracking-wide text-stone-500">Quantity</span>
|
||||||
<form
|
<form
|
||||||
action="{{ market_url('/product/' + p.slug + '/cart') }}"
|
action="{{ market_product_url(p.slug, 'cart', item.market_place) }}"
|
||||||
method="post"
|
method="post"
|
||||||
hx-post="{{ market_url('/product/' + p.slug + '/cart') }}"
|
hx-post="{{ market_product_url(p.slug, 'cart', item.market_place) }}"
|
||||||
hx-target="#cart-mini"
|
hx-target="#cart-mini"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
@@ -212,9 +212,9 @@
|
|||||||
{{ item.quantity }}
|
{{ item.quantity }}
|
||||||
</span>
|
</span>
|
||||||
<form
|
<form
|
||||||
action="{{ market_url('/product/' + p.slug + '/cart') }}"
|
action="{{ market_product_url(p.slug, 'cart', item.market_place) }}"
|
||||||
method="post"
|
method="post"
|
||||||
hx-post="{{ market_url('/product/' + p.slug + '/cart') }}"
|
hx-post="{{ market_product_url(p.slug, 'cart', item.market_place) }}"
|
||||||
hx-target="#cart-mini"
|
hx-target="#cart-mini"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from shared.browser.app.csrf import generate_csrf_token
|
|||||||
from shared.browser.app.authz import has_access
|
from shared.browser.app.authz import has_access
|
||||||
from shared.browser.app.filters import register as register_filters
|
from shared.browser.app.filters import register as register_filters
|
||||||
|
|
||||||
from .urls import coop_url, market_url, cart_url, events_url, login_url, page_cart_url
|
from .urls import coop_url, market_url, cart_url, events_url, login_url, page_cart_url, market_product_url
|
||||||
|
|
||||||
|
|
||||||
def setup_jinja(app: Quart) -> None:
|
def setup_jinja(app: Quart) -> None:
|
||||||
@@ -94,6 +94,7 @@ def setup_jinja(app: Quart) -> None:
|
|||||||
app.jinja_env.globals["events_url"] = events_url
|
app.jinja_env.globals["events_url"] = events_url
|
||||||
app.jinja_env.globals["login_url"] = login_url
|
app.jinja_env.globals["login_url"] = login_url
|
||||||
app.jinja_env.globals["page_cart_url"] = page_cart_url
|
app.jinja_env.globals["page_cart_url"] = page_cart_url
|
||||||
|
app.jinja_env.globals["market_product_url"] = market_product_url
|
||||||
|
|
||||||
# register jinja filters
|
# register jinja filters
|
||||||
register_filters(app)
|
register_filters(app)
|
||||||
|
|||||||
@@ -43,6 +43,24 @@ def page_cart_url(page_slug: str, path: str = "/") -> str:
|
|||||||
return cart_url(f"/{page_slug}{path}")
|
return cart_url(f"/{page_slug}{path}")
|
||||||
|
|
||||||
|
|
||||||
|
def market_product_url(product_slug: str, suffix: str = "", market_place=None) -> str:
|
||||||
|
"""Build a market product URL with the correct page/market prefix.
|
||||||
|
|
||||||
|
Resolves the prefix from:
|
||||||
|
- market app context: g.post_slug + g.market_slug
|
||||||
|
- cart app context: g.page_slug + market_place.slug
|
||||||
|
"""
|
||||||
|
from quart import g
|
||||||
|
|
||||||
|
page_slug = getattr(g, "post_slug", None) or getattr(g, "page_slug", None)
|
||||||
|
ms = getattr(g, "market_slug", None) or (
|
||||||
|
getattr(market_place, "slug", None) if market_place else None
|
||||||
|
)
|
||||||
|
prefix = f"/{page_slug}/{ms}" if page_slug and ms else ""
|
||||||
|
tail = f"/{suffix}" if suffix else "/"
|
||||||
|
return market_url(f"{prefix}/product/{product_slug}{tail}")
|
||||||
|
|
||||||
|
|
||||||
def login_url(next_url: str = "") -> str:
|
def login_url(next_url: str = "") -> str:
|
||||||
if next_url:
|
if next_url:
|
||||||
return coop_url(f"/auth/login/?next={quote(next_url, safe='')}")
|
return coop_url(f"/auth/login/?next={quote(next_url, safe='')}")
|
||||||
|
|||||||
Reference in New Issue
Block a user