Convert all 23 register_custom_layout calls to register_sx_layout across 6 services
Layout defcomps are now fully self-contained via IO-primitive auto-fetch macros, eliminating Python layout functions that manually threaded context values through SxExpr wrappers. Services converted: - Federation (1 layout): social - Blog (7 layouts): blog, blog-settings, blog-cache, blog-snippets, blog-menu-items, blog-tag-groups, blog-tag-group-edit - SX docs (2 layouts): sx, sx-section - Cart (2 layouts): cart-page, cart-admin + orders/order-detail - Events (9 layouts): calendar-admin, slots, slot, day-admin, entry, entry-admin, ticket-types, ticket-type, markets - Market (2 layouts): market, market-admin New IO primitives added to shared/sx/primitives_io.py: - federation-actor-ctx, cart-page-ctx, request-view-args - events-calendar-ctx, events-day-ctx, events-entry-ctx, events-slot-ctx, events-ticket-type-ctx - market-header-ctx (pre-builds desktop/mobile nav as SxExpr) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -228,6 +228,11 @@ def create_app() -> "Quart":
|
||||
("market", "container-nav", nav_params),
|
||||
], required=False)
|
||||
ctx["container_nav"] = events_nav + market_nav
|
||||
# Populate g._defpage_ctx for layout IO primitives
|
||||
if not hasattr(g, '_defpage_ctx'):
|
||||
g._defpage_ctx = {}
|
||||
g._defpage_ctx.setdefault("post", post_data.get("post"))
|
||||
g._defpage_ctx.setdefault("container_nav", ctx["container_nav"])
|
||||
return ctx
|
||||
|
||||
# --- oEmbed endpoint ---
|
||||
|
||||
@@ -1,42 +1,105 @@
|
||||
;; Market layout defcomps — root header via ~root-header-auto,
|
||||
;; market-specific headers passed as &key params.
|
||||
;; Market layout defcomps — fully self-contained via IO primitives.
|
||||
;; Registered via register_sx_layout in layouts.py.
|
||||
|
||||
;; --- Browse layout: root + post header + market header ---
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Auto-fetching market header macro
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~market-browse-layout-full (&key post-header market-header)
|
||||
(defmacro ~market-header-auto (oob)
|
||||
"Market header row using (market-header-ctx)."
|
||||
(quasiquote
|
||||
(let ((__mctx (market-header-ctx)))
|
||||
(~menu-row-sx :id "market-row" :level 2
|
||||
:link-href (get __mctx "link-href")
|
||||
:link-label-content (~market-shop-label
|
||||
:title (get __mctx "market-title")
|
||||
:top-slug (get __mctx "top-slug")
|
||||
:sub-div (get __mctx "sub-slug"))
|
||||
:nav (get __mctx "desktop-nav")
|
||||
:child-id "market-header-child"
|
||||
:oob (unquote oob)))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; OOB clear helpers
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~market-clear-oob ()
|
||||
"Clear OOB divs for browse level."
|
||||
(<>
|
||||
(~clear-oob-div :id "product-admin-row")
|
||||
(~clear-oob-div :id "product-admin-header-child")
|
||||
(~clear-oob-div :id "product-row")
|
||||
(~clear-oob-div :id "product-header-child")
|
||||
(~clear-oob-div :id "market-admin-row")
|
||||
(~clear-oob-div :id "market-admin-header-child")
|
||||
(~clear-oob-div :id "post-admin-row")
|
||||
(~clear-oob-div :id "post-admin-header-child")))
|
||||
|
||||
(defcomp ~market-clear-oob-admin ()
|
||||
"Clear OOB divs for admin level."
|
||||
(<>
|
||||
(~clear-oob-div :id "product-admin-row")
|
||||
(~clear-oob-div :id "product-admin-header-child")
|
||||
(~clear-oob-div :id "product-row")
|
||||
(~clear-oob-div :id "product-header-child")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Browse layout: root + post + market (self-contained)
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~market-browse-layout-full ()
|
||||
(<> (~root-header-auto)
|
||||
(~header-child-sx :inner (<> post-header market-header))))
|
||||
(~header-child-sx
|
||||
:inner (<> (~post-header-auto nil)
|
||||
(~market-header-auto nil)))))
|
||||
|
||||
(defcomp ~market-browse-layout-oob (&key oob-header post-header-oob clear-oob)
|
||||
(<> oob-header post-header-oob clear-oob))
|
||||
(defcomp ~market-browse-layout-oob ()
|
||||
(<> (~post-header-auto true)
|
||||
(~oob-header-sx :parent-id "post-header-child"
|
||||
:row (~market-header-auto nil))
|
||||
(~market-clear-oob)
|
||||
(~root-header-auto true)))
|
||||
|
||||
;; --- Product layout: root + post + market + product ---
|
||||
(defcomp ~market-browse-layout-mobile ()
|
||||
(let ((__mctx (market-header-ctx)))
|
||||
(get __mctx "mobile-nav")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Market admin layout: root + post + market + post-admin (self-contained)
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~market-admin-layout-full (&key selected)
|
||||
(<> (~root-header-auto)
|
||||
(~header-child-sx
|
||||
:inner (<> (~post-header-auto nil)
|
||||
(~market-header-auto nil)
|
||||
(~post-admin-header-auto nil selected)))))
|
||||
|
||||
(defcomp ~market-admin-layout-oob (&key selected)
|
||||
(<> (~market-header-auto true)
|
||||
(~oob-header-sx :parent-id "market-header-child"
|
||||
:row (~post-admin-header-auto nil selected))
|
||||
(~market-clear-oob-admin)
|
||||
(~root-header-auto true)))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Parameterized defcomps — used by renders.py (non-defpage routes)
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
;; Product layout: root + post + market + product
|
||||
(defcomp ~market-product-layout-full (&key post-header market-header product-header)
|
||||
(<> (~root-header-auto)
|
||||
(~header-child-sx :inner (<> post-header market-header product-header))))
|
||||
|
||||
;; --- Product admin layout: root + post + market + product + admin ---
|
||||
|
||||
;; Product admin layout: root + post + market + product + admin
|
||||
(defcomp ~market-product-admin-layout-full (&key post-header market-header product-header admin-header)
|
||||
(<> (~root-header-auto)
|
||||
(~header-child-sx :inner (<> post-header market-header product-header admin-header))))
|
||||
|
||||
;; --- Market admin layout: root + post + market + market-admin ---
|
||||
|
||||
(defcomp ~market-admin-layout-full (&key post-header market-header admin-header)
|
||||
(<> (~root-header-auto)
|
||||
(~header-child-sx :inner (<> post-header market-header admin-header))))
|
||||
|
||||
(defcomp ~market-admin-layout-oob (&key market-header-oob admin-oob-header clear-oob)
|
||||
(<> market-header-oob admin-oob-header clear-oob))
|
||||
|
||||
;; --- OOB wrappers ---
|
||||
|
||||
;; OOB wrappers
|
||||
(defcomp ~market-oob-wrap (&key parts)
|
||||
(<> parts))
|
||||
|
||||
;; --- Content wrappers ---
|
||||
|
||||
;; Content wrappers
|
||||
(defcomp ~market-content-padded (&key content)
|
||||
(<> content (div :class "pb-8")))
|
||||
|
||||
@@ -4,15 +4,9 @@ from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
from shared.sx.parser import SxExpr
|
||||
from shared.sx.helpers import (
|
||||
sx_call,
|
||||
post_header_sx as _post_header_sx,
|
||||
post_admin_header_sx,
|
||||
oob_header_sx as _oob_header_sx,
|
||||
header_child_sx,
|
||||
)
|
||||
from shared.sx.helpers import sx_call
|
||||
|
||||
from .utils import _set_prices, _price_str, _clear_deeper_oob
|
||||
from .utils import _set_prices, _price_str
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -272,62 +266,14 @@ def _product_admin_header_sx(ctx: dict, d: dict, *, oob: bool = False) -> str:
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Market admin header
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def _market_admin_header_sx(ctx: dict, *, oob: bool = False, selected: str = "") -> str:
|
||||
"""Build market admin header row -- delegates to shared helper."""
|
||||
slug = (ctx.get("post") or {}).get("slug", "")
|
||||
return await post_admin_header_sx(ctx, slug, oob=oob, selected=selected)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# Layout registration
|
||||
# Layout registration — all layouts delegate to .sx defcomps
|
||||
# ===========================================================================
|
||||
|
||||
def _register_market_layouts() -> None:
|
||||
from shared.sx.layouts import register_custom_layout
|
||||
register_custom_layout("market", _market_full, _market_oob, _market_mobile)
|
||||
register_custom_layout("market-admin", _market_admin_full, _market_admin_oob)
|
||||
|
||||
|
||||
async def _market_full(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env
|
||||
return await render_to_sx_with_env("market-browse-layout-full", {},
|
||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
||||
market_header=SxExpr(_market_header_sx(ctx)))
|
||||
|
||||
|
||||
async def _market_oob(ctx: dict, **kw: Any) -> str:
|
||||
oob_hdr = await _oob_header_sx("post-header-child", "market-header-child",
|
||||
_market_header_sx(ctx))
|
||||
return sx_call("market-browse-layout-oob",
|
||||
oob_header=SxExpr(oob_hdr),
|
||||
post_header_oob=SxExpr(await _post_header_sx(ctx, oob=True)),
|
||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child")))
|
||||
|
||||
|
||||
def _market_mobile(ctx: dict, **kw: Any) -> str:
|
||||
return _mobile_nav_panel_sx(ctx)
|
||||
|
||||
|
||||
async def _market_admin_full(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env
|
||||
selected = kw.get("selected", "")
|
||||
return await render_to_sx_with_env("market-admin-layout-full", {},
|
||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
||||
market_header=SxExpr(_market_header_sx(ctx)),
|
||||
admin_header=SxExpr(await _market_admin_header_sx(ctx, selected=selected)))
|
||||
|
||||
|
||||
async def _market_admin_oob(ctx: dict, **kw: Any) -> str:
|
||||
selected = kw.get("selected", "")
|
||||
return sx_call("market-admin-layout-oob",
|
||||
market_header_oob=SxExpr(_market_header_sx(ctx, oob=True)),
|
||||
admin_oob_header=SxExpr(await _oob_header_sx("market-header-child", "market-admin-header-child",
|
||||
await _market_admin_header_sx(ctx, selected=selected))),
|
||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child",
|
||||
"market-admin-row", "market-admin-header-child")))
|
||||
from shared.sx.layouts import register_sx_layout
|
||||
register_sx_layout("market",
|
||||
"market-browse-layout-full", "market-browse-layout-oob",
|
||||
"market-browse-layout-mobile")
|
||||
register_sx_layout("market-admin",
|
||||
"market-admin-layout-full", "market-admin-layout-oob")
|
||||
|
||||
Reference in New Issue
Block a user