Move market composition from Python to .sx defcomps (Phase 3)

Python sxc/pages/ functions no longer build nested sx_call chains or
reference leaf component names. Instead they extract data (URLs, prices,
CSRF, cart state) and call a single top-level composition defcomp with
pure data values. The .sx defcomps handle all component-to-component
wiring, iteration (map), and conditional rendering.

New .sx composition defcomps:
- headers.sx: ~market-header-from-data, ~market-desktop-nav-from-data,
  ~market-product-header-from-data, ~market-product-admin-header-from-data
- prices.sx: ~market-prices-header-from-data, ~market-card-price-from-data
- navigation.sx: ~market-mobile-nav-from-data
- cards.sx: ~market-product-cards-content, ~market-card-from-data,
  ~market-cards-content, ~market-landing-from-data
- detail.sx: ~market-product-detail-from-data, ~market-detail-gallery-from-data,
  ~market-detail-info-from-data
- meta.sx: ~market-product-meta-from-data
- filters.sx: ~market-desktop-filter-from-data, ~market-mobile-chips-from-data,
  ~market-mobile-filter-content-from-data, plus 6 sub-composition defcomps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 01:11:57 +00:00
parent 36a0bd8577
commit e81d77437e
12 changed files with 961 additions and 781 deletions

View File

@@ -11,7 +11,7 @@ from shared.sx.helpers import (
full_page_sx, oob_page_sx,
)
from .utils import _set_prices, _price_str, _clear_deeper_oob, _product_detail_sx, _product_meta_sx
from .utils import _clear_deeper_oob, _product_detail_sx, _product_meta_sx
from .cards import _product_cards_sx, _market_cards_sx
from .filters import _desktop_filter_sx, _mobile_filter_summary_sx
from .layouts import (
@@ -36,9 +36,7 @@ async def render_browse_page(ctx: dict) -> str:
content = _product_grid(cards)
from shared.sx.helpers import render_to_sx_with_env
hdr = await render_to_sx_with_env("market-browse-layout-full", {},
post_header=await _post_header_sx(ctx),
market_header=_market_header_sx(ctx))
hdr = await render_to_sx_with_env("market-browse-layout-full", {})
menu = _mobile_nav_panel_sx(ctx)
filter_sx = await _mobile_filter_summary_sx(ctx)
aside_sx = await _desktop_filter_sx(ctx)
@@ -52,13 +50,8 @@ async def render_browse_oob(ctx: dict) -> str:
cards = _product_cards_sx(ctx)
content = _product_grid(cards)
oob_hdr = await _oob_header_sx("post-header-child", "market-header-child",
_market_header_sx(ctx))
oobs = sx_call("market-browse-layout-oob",
oob_header=oob_hdr,
post_header_oob=await _post_header_sx(ctx, oob=True),
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
"market-row", "market-header-child")))
# Layout handles all OOB headers via auto-fetch macros
oobs = sx_call("market-browse-layout-oob")
menu = _mobile_nav_panel_sx(ctx)
filter_sx = await _mobile_filter_summary_sx(ctx)
aside_sx = await _desktop_filter_sx(ctx)
@@ -207,7 +200,7 @@ def render_cart_added_response(cart: list, item: Any, d: dict) -> str:
Returns OOB fragments: cart-mini icon + product add/remove buttons + cart item row.
"""
from shared.browser.app.csrf import generate_csrf_token
from quart import url_for, g
from quart import url_for
from shared.infrastructure.urls import cart_url as _cart_url
csrf = generate_csrf_token()