diff --git a/account/sx/layouts.sx b/account/sx/layouts.sx index 19c028a..10052e5 100644 --- a/account/sx/layouts.sx +++ b/account/sx/layouts.sx @@ -1,33 +1,20 @@ -;; Account layout defcomps — read ctx values from env free variables. +;; Account layout defcomps — fully self-contained via IO primitives. ;; Registered via register_sx_layout("account", ...) in __init__.py. -;; Free variables come from _ctx_to_env() in shared/sx/helpers.py. ;; Full page: root header + auth header row in header-child (defcomp ~account-layout-full () - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx - :inner (~auth-header-row :account-url account-url - :select-colours select-colours - :account-nav account-nav)))) + :inner (~auth-header-row-auto)))) ;; OOB (HTMX): auth row + root header, both with oob=true (defcomp ~account-layout-oob () - (<> (~auth-header-row :account-url account-url - :select-colours select-colours - :account-nav account-nav - :oob true) - (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin - :oob true))) + (<> (~auth-header-row-auto true) + (~root-header-auto true))) ;; Mobile menu: auth section + root nav (defcomp ~account-layout-mobile () (<> (~mobile-menu-section :label "account" :href "/" :level 1 :colour "sky" - :items (~auth-nav-items :account-url account-url - :select-colours select-colours - :account-nav account-nav)) - (~root-mobile :nav-tree nav-tree :auth-menu auth-menu))) + :items (~auth-nav-items-auto)) + (~root-mobile-auto))) diff --git a/blog/sx/admin.sx b/blog/sx/admin.sx index b78233d..95172ec 100644 --- a/blog/sx/admin.sx +++ b/blog/sx/admin.sx @@ -170,6 +170,15 @@ (summary :class "cursor-pointer px-4 py-3 font-medium text-sm bg-stone-100 hover:bg-stone-200 select-none" title) (div :class "p-4 overflow-x-auto text-xs" content))) +(defcomp ~blog-preview-rendered (&key html) + (div :class "blog-content prose max-w-none" (raw! html))) + +(defcomp ~blog-preview-empty () + (div :class "p-8 text-stone-500" "No content to preview.")) + +(defcomp ~blog-admin-placeholder () + (div :class "pb-8")) + ;; --------------------------------------------------------------------------- ;; Data-driven content defcomps (called from defpages with service data) ;; --------------------------------------------------------------------------- diff --git a/blog/sx/layouts.sx b/blog/sx/layouts.sx index 9058011..a1fe5e5 100644 --- a/blog/sx/layouts.sx +++ b/blog/sx/layouts.sx @@ -1,37 +1,38 @@ -;; Blog layout defcomps — root header from env free variables, -;; blog-specific headers passed as &key params. +;; Blog layout defcomps — fully self-contained via IO primitives. -;; --- Blog layout (root + invisible blog header) --- +;; --- Blog header (invisible row for blog-header-child swap target) --- -(defcomp ~blog-layout-full (&key blog-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) - blog-header)) +(defcomp ~blog-header (&key oob) + (~menu-row-sx :id "blog-row" :level 1 + :link-label-content (div) + :child-id "blog-header-child" :oob oob)) + +;; --- Blog layout (root + blog header) --- + +(defcomp ~blog-layout-full () + (<> (~root-header-auto) + (~blog-header))) ;; --- Settings layout (root + settings header) --- (defcomp ~settings-layout-full (&key settings-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) settings-header)) ;; --- Sub-settings layout (root + settings + sub row) --- (defcomp ~sub-settings-layout-full (&key settings-header sub-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) settings-header sub-header)) (defcomp ~sub-settings-layout-oob (&key settings-header-oob sub-header-oob) (<> settings-header-oob sub-header-oob)) -;; --- Settings nav links (replaces Python _settings_nav_sx loop) --- +;; --- Settings nav links — uses (select-colours) IO primitive --- -(defcomp ~blog-settings-nav (&key select-colours) - (let* ((links (list +(defcomp ~blog-settings-nav () + (let* ((sc (select-colours)) + (links (list (dict :endpoint "menu_items.defpage_menu_items_page" :icon "fa fa-bars" :label "Menu Items") (dict :endpoint "snippets.defpage_snippets_page" :icon "fa fa-puzzle-piece" :label "Snippets") (dict :endpoint "blog.tag_groups_admin.defpage_tag_groups_page" :icon "fa fa-tags" :label "Tag Groups") @@ -41,7 +42,7 @@ :href (url-for (get lnk "endpoint")) :icon (get lnk "icon") :label (get lnk "label") - :select-colours (or select-colours ""))) + :select-colours (or sc ""))) links)))) ;; --- Editor panel wrapper --- diff --git a/blog/sxc/pages/helpers.py b/blog/sxc/pages/helpers.py index 4c75d33..bc4b900 100644 --- a/blog/sxc/pages/helpers.py +++ b/blog/sxc/pages/helpers.py @@ -140,7 +140,8 @@ async def _h_editor_page_content(**kw): async def _h_post_admin_content(slug=None, **kw): await _ensure_post_data(slug) - return '(div :class "pb-8")' + from shared.sx.helpers import render_to_sx + return await render_to_sx("blog-admin-placeholder") async def _h_post_data_content(slug=None, **kw): @@ -264,7 +265,7 @@ async def _h_post_preview_content(slug=None, **kw): from quart import g from shared.services.registry import services from shared.sx.helpers import render_to_sx - from shared.sx.parser import SxExpr, serialize as sx_serialize + from shared.sx.parser import SxExpr preview = await services.blog_page.preview_data(g.s) @@ -276,16 +277,16 @@ async def _h_post_preview_content(slug=None, **kw): sections.append(await render_to_sx("blog-preview-section", title="Lexical JSON", content=SxExpr(preview["json_pretty"]))) if preview.get("sx_rendered"): - rendered_sx = f'(div :class "blog-content prose max-w-none" (raw! {sx_serialize(preview["sx_rendered"])}))' + rendered_sx = await render_to_sx("blog-preview-rendered", html=preview["sx_rendered"]) sections.append(await render_to_sx("blog-preview-section", title="SX Rendered", content=SxExpr(rendered_sx))) if preview.get("lex_rendered"): - rendered_sx = f'(div :class "blog-content prose max-w-none" (raw! {sx_serialize(preview["lex_rendered"])}))' + rendered_sx = await render_to_sx("blog-preview-rendered", html=preview["lex_rendered"]) sections.append(await render_to_sx("blog-preview-section", title="Lexical Rendered", content=SxExpr(rendered_sx))) if not sections: - return '(div :class "p-8 text-stone-500" "No content to preview.")' + return await render_to_sx("blog-preview-empty") inner = " ".join(sections) return await render_to_sx("blog-preview-panel", sections=SxExpr(f"(<> {inner})")) diff --git a/blog/sxc/pages/layouts.py b/blog/sxc/pages/layouts.py index aeb22c6..36eb7f3 100644 --- a/blog/sxc/pages/layouts.py +++ b/blog/sxc/pages/layouts.py @@ -8,15 +8,6 @@ from typing import Any # Header helpers (moved from sx_components — thin render_to_sx wrappers) # --------------------------------------------------------------------------- -async def _blog_header_sx(ctx: dict, *, oob: bool = False) -> str: - from shared.sx.helpers import render_to_sx - from shared.sx.parser import SxExpr - return await render_to_sx("menu-row-sx", - id="blog-row", level=1, - link_label_content=SxExpr("(div)"), - child_id="blog-header-child", oob=oob) - - async def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str: from shared.sx.helpers import render_to_sx from shared.sx.parser import SxExpr @@ -36,8 +27,7 @@ async def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str: async def _settings_nav_sx(ctx: dict) -> str: from shared.sx.helpers import render_to_sx - return await render_to_sx("blog-settings-nav", - select_colours=ctx.get("select_colours", "")) + return await render_to_sx("blog-settings-nav") async def _sub_settings_header_sx(row_id: str, child_id: str, href: str, @@ -76,33 +66,29 @@ def _register_blog_layouts() -> None: # --- Blog layout (root + blog header) --- async def _blog_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env - from shared.sx.parser import SxExpr - return await render_to_sx_with_env("blog-layout-full", _ctx_to_env(ctx), - blog_header=SxExpr(await _blog_header_sx(ctx))) + from shared.sx.helpers import render_to_sx_with_env + return await render_to_sx_with_env("blog-layout-full", {}) async def _blog_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx - from shared.sx.parser import SxExpr - rows = await render_to_sx_with_env("blog-layout-full", _ctx_to_env(ctx), - blog_header=SxExpr(await _blog_header_sx(ctx))) + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx + rows = await render_to_sx_with_env("blog-layout-full", {}) return await oob_header_sx("root-header-child", "blog-header-child", rows) # --- Settings layout (root + settings header) --- async def _settings_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("settings-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("settings-layout-full", {}, settings_header=SxExpr(await _settings_header_sx(ctx))) async def _settings_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - rows = await render_to_sx_with_env("settings-layout-full", _ctx_to_env(ctx), + rows = await render_to_sx_with_env("settings-layout-full", {}, settings_header=SxExpr(await _settings_header_sx(ctx))) return await oob_header_sx("root-header-child", "root-settings-header-child", rows) @@ -115,10 +101,10 @@ async def _settings_mobile(ctx: dict, **kw: Any) -> str: async def _sub_settings_full(ctx: dict, row_id: str, child_id: str, endpoint: str, icon: str, label: str) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr from quart import url_for as qurl - return await render_to_sx_with_env("sub-settings-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("sub-settings-layout-full", {}, settings_header=SxExpr(await _settings_header_sx(ctx)), sub_header=SxExpr(await _sub_settings_header_sx( row_id, child_id, qurl(endpoint), icon, label, ctx))) @@ -190,10 +176,10 @@ async def _tag_groups_oob(ctx: dict, **kw: Any) -> str: async def _tag_group_edit_full(ctx: dict, **kw: Any) -> str: from quart import request, url_for as qurl - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr g_id = (request.view_args or {}).get("id") - return await render_to_sx_with_env("sub-settings-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("sub-settings-layout-full", {}, settings_header=SxExpr(await _settings_header_sx(ctx)), sub_header=SxExpr(await _sub_settings_header_sx( "tag-groups-row", "tag-groups-header-child", diff --git a/cart/sx/header.sx b/cart/sx/header.sx index 692be37..1fc17bf 100644 --- a/cart/sx/header.sx +++ b/cart/sx/header.sx @@ -3,6 +3,11 @@ (defcomp ~cart-page-label-img (&key src) (img :src src :class "h-8 w-8 rounded-full object-cover border border-stone-300 flex-shrink-0")) +(defcomp ~cart-page-label (&key feature-image title) + (<> (when feature-image + (~cart-page-label-img :src feature-image)) + (span title))) + (defcomp ~cart-all-carts-link (&key href) (a :href href :class "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-stone-300 bg-white hover:bg-stone-50 transition" (i :class "fa fa-arrow-left text-xs" :aria-hidden "true") "All carts")) diff --git a/cart/sx/layouts.sx b/cart/sx/layouts.sx index bb34148..1bdfaf9 100644 --- a/cart/sx/layouts.sx +++ b/cart/sx/layouts.sx @@ -1,12 +1,9 @@ -;; Cart layout defcomps — root header from env free variables, -;; cart-specific headers passed as &key params. +;; Cart layout defcomps — fully self-contained via IO primitives. ;; --- cart-page layout: root + cart row + page-cart row --- (defcomp ~cart-page-layout-full (&key cart-row page-cart-row) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx :inner (<> cart-row (~header-child-sx :id "cart-header-child" :inner page-cart-row))))) @@ -19,40 +16,31 @@ ;; --- cart-admin layout: root + post header + admin header --- (defcomp ~cart-admin-layout-full (&key post-header admin-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) post-header admin-header)) ;; --- orders-within-cart: root + auth-simple + orders --- (defcomp ~cart-orders-layout-full (&key list-url) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx - :inner (<> (~auth-header-row-simple :account-url account-url) + :inner (<> (~auth-header-row-simple-auto) (~header-child-sx :id "auth-header-child" :inner (~orders-header-row :list-url list-url)))))) (defcomp ~cart-orders-layout-oob (&key list-url) - (<> (~auth-header-row-simple :account-url account-url :oob true) + (<> (~auth-header-row-simple-auto true) (~oob-header-sx :parent-id "auth-header-child" :row (~orders-header-row :list-url list-url)) - (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin - :oob true))) + (~root-header-auto true))) ;; --- order-detail-within-cart: root + auth-simple + orders + order --- (defcomp ~cart-order-detail-layout-full (&key list-url detail-url order-label) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx - :inner (<> (~auth-header-row-simple :account-url account-url) + :inner (<> (~auth-header-row-simple-auto) (~header-child-sx :id "auth-header-child" :inner (<> (~orders-header-row :list-url list-url) (~header-child-sx :id "orders-header-child" @@ -67,10 +55,7 @@ :row (~menu-row-sx :id "order-row" :level 3 :colour "sky" :link-href detail-url :link-label order-label :icon "fa fa-gbp" :oob true)) - (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin - :oob true))) + (~root-header-auto true))) ;; --- orders rows wrapper (for infinite scroll) --- diff --git a/cart/sxc/pages/layouts.py b/cart/sxc/pages/layouts.py index 1591129..9b4c981 100644 --- a/cart/sxc/pages/layouts.py +++ b/cart/sxc/pages/layouts.py @@ -3,7 +3,6 @@ from __future__ import annotations from typing import Any -from markupsafe import escape from shared.sx.parser import SxExpr @@ -73,11 +72,9 @@ async def _page_cart_header_sx(ctx: dict, page_post: Any, *, oob: bool = False) from shared.sx.helpers import render_to_sx, call_url slug = page_post.slug if page_post else "" title = ((page_post.title if page_post else None) or "")[:160] - label_parts = [] - if page_post and page_post.feature_image: - label_parts.append(await render_to_sx("cart-page-label-img", src=page_post.feature_image)) - label_parts.append(f'(span "{escape(title)}")') - label_sx = "(<> " + " ".join(label_parts) + ")" + label_sx = await render_to_sx("cart-page-label", + feature_image=page_post.feature_image if page_post else None, + title=title) nav_sx = await render_to_sx("cart-all-carts-link", href=call_url(ctx, "cart_url", "/")) return await render_to_sx( "menu-row-sx", @@ -101,9 +98,9 @@ async def _cart_page_admin_header_sx(ctx: dict, page_post: Any, *, oob: bool = F # --------------------------------------------------------------------------- async def _cart_page_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env page_post = ctx.get("page_post") - env = _ctx_to_env(ctx) + env = {} return await render_to_sx_with_env("cart-page-layout-full", env, cart_row=SxExpr(await _cart_header_sx(ctx)), page_cart_row=SxExpr(await _page_cart_header_sx(ctx, page_post)), @@ -111,9 +108,9 @@ async def _cart_page_full(ctx: dict, **kw: Any) -> str: async def _cart_page_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, root_header_sx + from shared.sx.helpers import render_to_sx_with_env, root_header_sx page_post = ctx.get("page_post") - env = _ctx_to_env(ctx, oob=True) + env = {} return await render_to_sx_with_env("cart-page-layout-oob", env, root_header_oob=SxExpr(await root_header_sx(ctx, oob=True)), cart_row_oob=SxExpr(await _cart_header_sx(ctx, oob=True)), @@ -122,10 +119,10 @@ async def _cart_page_oob(ctx: dict, **kw: Any) -> str: async def _cart_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env page_post = ctx.get("page_post") selected = kw.get("selected", "") - env = _ctx_to_env(ctx) + env = {} return await render_to_sx_with_env("cart-admin-layout-full", env, post_header=SxExpr(await _post_header_sx(ctx, page_post)), admin_header=SxExpr(await _cart_page_admin_header_sx(ctx, page_post, selected=selected)), diff --git a/cart/sxc/pages/renders.py b/cart/sxc/pages/renders.py index f53027e..125d53c 100644 --- a/cart/sxc/pages/renders.py +++ b/cart/sxc/pages/renders.py @@ -7,7 +7,7 @@ from .utils import _serialize_order, _serialize_calendar_entry async def render_orders_page(ctx, orders, page, total_pages, search, search_count, url_for_fn, qs_fn): - from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env, search_desktop_sx, search_mobile_sx, full_page_sx + from shared.sx.helpers import render_to_sx, render_to_sx_with_env, search_desktop_sx, search_mobile_sx, full_page_sx from shared.utils import route_prefix ctx["search"] = search ctx["search_count"] = search_count @@ -17,7 +17,7 @@ async def render_orders_page(ctx, orders, page, total_pages, search, search_coun order_dicts = [_serialize_order(o) for o in orders] content = await render_to_sx("orders-list-content", orders=order_dicts, page=page, total_pages=total_pages, rows_url=list_url, detail_url_prefix=detail_url_prefix) - header_rows = await render_to_sx_with_env("cart-orders-layout-full", _ctx_to_env(ctx), + header_rows = await render_to_sx_with_env("cart-orders-layout-full", {}, list_url=list_url, ) filt = await render_to_sx("order-list-header", search_mobile=SxExpr(await search_mobile_sx(ctx))) @@ -49,7 +49,7 @@ async def render_orders_rows(ctx, orders, page, total_pages, url_for_fn, qs_fn): async def render_orders_oob(ctx, orders, page, total_pages, search, search_count, url_for_fn, qs_fn): - from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env, search_desktop_sx, search_mobile_sx, oob_page_sx + from shared.sx.helpers import render_to_sx, render_to_sx_with_env, search_desktop_sx, search_mobile_sx, oob_page_sx from shared.utils import route_prefix ctx["search"] = search ctx["search_count"] = search_count @@ -59,7 +59,7 @@ async def render_orders_oob(ctx, orders, page, total_pages, search, search_count order_dicts = [_serialize_order(o) for o in orders] content = await render_to_sx("orders-list-content", orders=order_dicts, page=page, total_pages=total_pages, rows_url=list_url, detail_url_prefix=detail_url_prefix) - oobs = await render_to_sx_with_env("cart-orders-layout-oob", _ctx_to_env(ctx, oob=True), + oobs = await render_to_sx_with_env("cart-orders-layout-oob", {}, list_url=list_url, ) filt = await render_to_sx("order-list-header", search_mobile=SxExpr(await search_mobile_sx(ctx))) @@ -67,7 +67,7 @@ async def render_orders_oob(ctx, orders, page, total_pages, search, search_count async def render_order_page(ctx, order, calendar_entries, url_for_fn): - from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env, full_page_sx + from shared.sx.helpers import render_to_sx, render_to_sx_with_env, full_page_sx from shared.utils import route_prefix from shared.browser.app.csrf import generate_csrf_token pfx = route_prefix() @@ -80,7 +80,7 @@ async def render_order_page(ctx, order, calendar_entries, url_for_fn): main = await render_to_sx("order-detail-content", order=order_data, calendar_entries=cal_data) filt = await render_to_sx("order-detail-filter-content", order=order_data, list_url=list_url, recheck_url=recheck_url, pay_url=pay_url, csrf=generate_csrf_token()) - header_rows = await render_to_sx_with_env("cart-order-detail-layout-full", _ctx_to_env(ctx), + header_rows = await render_to_sx_with_env("cart-order-detail-layout-full", {}, list_url=list_url, detail_url=detail_url, order_label=f"Order {order.id}", ) @@ -88,7 +88,7 @@ async def render_order_page(ctx, order, calendar_entries, url_for_fn): async def render_order_oob(ctx, order, calendar_entries, url_for_fn): - from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env, oob_page_sx + from shared.sx.helpers import render_to_sx, render_to_sx_with_env, oob_page_sx from shared.utils import route_prefix from shared.browser.app.csrf import generate_csrf_token pfx = route_prefix() @@ -101,7 +101,7 @@ async def render_order_oob(ctx, order, calendar_entries, url_for_fn): main = await render_to_sx("order-detail-content", order=order_data, calendar_entries=cal_data) filt = await render_to_sx("order-detail-filter-content", order=order_data, list_url=list_url, recheck_url=recheck_url, pay_url=pay_url, csrf=generate_csrf_token()) - oobs = await render_to_sx_with_env("cart-order-detail-layout-oob", _ctx_to_env(ctx, oob=True), + oobs = await render_to_sx_with_env("cart-order-detail-layout-oob", {}, detail_url=detail_url, order_label=f"Order {order.id}", ) @@ -109,11 +109,11 @@ async def render_order_oob(ctx, order, calendar_entries, url_for_fn): async def render_checkout_error_page(ctx, error=None, order=None): - from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env, full_page_sx + from shared.sx.helpers import render_to_sx, render_to_sx_with_env, full_page_sx from shared.infrastructure.urls import cart_url err_msg = error or "Unexpected error while creating the hosted checkout session." order_sx = await render_to_sx("checkout-error-order-id", oid=f"#{order.id}") if order else None - hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + hdr = await render_to_sx_with_env("layout-root-full", {}) filt = await render_to_sx("checkout-error-header") content = await render_to_sx("checkout-error-content", msg=err_msg, order=SxExpr(order_sx) if order_sx else None, back_url=cart_url("/")) diff --git a/events/sx/header.sx b/events/sx/header.sx index 1aec230..0f62026 100644 --- a/events/sx/header.sx +++ b/events/sx/header.sx @@ -24,3 +24,10 @@ (div :id (str "entry-title-" entry-id) :class "flex gap-1 items-center" title times)) +(defcomp ~events-slot-label (&key name description) + (div :class "flex flex-col md:flex-row md:gap-2 items-center" + (div :class "flex flex-row items-center gap-2" + (i :class "fa fa-clock") + (div :class "shrink-0" name)) + (p :class "text-stone-500 whitespace-pre-line break-all w-full" description))) + diff --git a/events/sx/layouts.sx b/events/sx/layouts.sx index 2ba7825..81ff1a8 100644 --- a/events/sx/layouts.sx +++ b/events/sx/layouts.sx @@ -1,13 +1,11 @@ -;; Events layout defcomps — root header from env free variables, +;; Events layout defcomps — root header via ~root-header-auto, ;; events-specific headers passed as &key params. ;; --- Calendar admin layout: root + post + child(admin + cal + cal-admin) --- (defcomp ~events-cal-admin-layout-full (&key post-header admin-header calendar-header calendar-admin-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) post-header (~header-child-sx :inner (<> admin-header calendar-header calendar-admin-header)))) @@ -23,9 +21,7 @@ (defcomp ~events-slot-layout-full (&key post-header admin-header calendar-header calendar-admin-header slot-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) post-header (~header-child-sx :inner (<> admin-header calendar-header calendar-admin-header slot-header)))) @@ -36,9 +32,7 @@ (defcomp ~events-day-admin-layout-full (&key post-header admin-header calendar-header day-header day-admin-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) post-header (~header-child-sx :inner (<> admin-header calendar-header day-header day-admin-header)))) @@ -48,9 +42,7 @@ ;; --- Entry layout: root + child(post + cal + day + entry) --- (defcomp ~events-entry-layout-full (&key post-header calendar-header day-header entry-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx :inner (<> post-header calendar-header day-header entry-header)))) (defcomp ~events-entry-layout-oob (&key day-oob entry-oob-wrap clear-oob) @@ -61,9 +53,7 @@ (defcomp ~events-entry-admin-layout-full (&key post-header admin-header calendar-header day-header entry-header entry-admin-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) post-header (~header-child-sx :inner (<> admin-header calendar-header day-header entry-header entry-admin-header)))) @@ -76,9 +66,7 @@ (defcomp ~events-ticket-types-layout-full (&key post-header calendar-header day-header entry-header entry-admin-header ticket-types-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx :inner (<> post-header calendar-header day-header entry-header entry-admin-header ticket-types-header)))) @@ -90,9 +78,7 @@ (defcomp ~events-ticket-type-layout-full (&key post-header calendar-header day-header entry-header entry-admin-header ticket-types-header ticket-type-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx :inner (<> post-header calendar-header day-header entry-header entry-admin-header ticket-types-header ticket-type-header)))) @@ -103,9 +89,7 @@ ;; --- Markets layout: root + child(post + markets) --- (defcomp ~events-markets-layout-full (&key post-header markets-header) - (<> (~root-header :cart-mini cart-mini :blog-url blog-url :site-title site-title - :app-label app-label :nav-tree nav-tree :auth-menu auth-menu - :nav-panel nav-panel :settings-url settings-url :is-admin is-admin) + (<> (~root-header-auto) (~header-child-sx :inner (<> post-header markets-header)))) (defcomp ~events-markets-layout-oob (&key post-oob markets-oob-wrap) diff --git a/events/sxc/pages/calendar.py b/events/sxc/pages/calendar.py index ab22d5f..28bb587 100644 --- a/events/sxc/pages/calendar.py +++ b/events/sxc/pages/calendar.py @@ -2,7 +2,7 @@ from __future__ import annotations from shared.sx.helpers import ( - call_url, render_to_sx, render_to_sx_with_env, _ctx_to_env, + call_url, render_to_sx, render_to_sx_with_env, post_admin_header_sx, ) from shared.sx.parser import SxExpr diff --git a/events/sxc/pages/entries.py b/events/sxc/pages/entries.py index 4516acb..5c9bdec 100644 --- a/events/sxc/pages/entries.py +++ b/events/sxc/pages/entries.py @@ -3,7 +3,7 @@ from __future__ import annotations from markupsafe import escape -from shared.sx.helpers import render_to_sx, render_to_sx_with_env, _ctx_to_env +from shared.sx.helpers import render_to_sx, render_to_sx_with_env from shared.sx.parser import SxExpr from .utils import ( diff --git a/events/sxc/pages/helpers.py b/events/sxc/pages/helpers.py index 91be5d1..8604e05 100644 --- a/events/sxc/pages/helpers.py +++ b/events/sxc/pages/helpers.py @@ -228,11 +228,11 @@ def _register_events_layouts() -> None: # --- Calendar admin layout (root + post + child(post-admin + calendar + cal-admin)) --- async def _cal_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-cal-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-cal-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -241,11 +241,11 @@ async def _cal_admin_full(ctx: dict, **kw: Any) -> str: async def _cal_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-cal-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-cal-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_oob=SxExpr(await _calendar_header_sx(ctx, oob=True)), cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child", @@ -264,11 +264,11 @@ async def _slots_full(ctx: dict, **kw: Any) -> str: async def _slots_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slots-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-slots-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_admin_oob=SxExpr(await _calendar_admin_header_sx(ctx, oob=True)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", @@ -281,11 +281,11 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: # --- Slot detail layout (extends cal-admin with slot header) --- async def _slot_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slot-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-slot-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -295,11 +295,11 @@ async def _slot_full(ctx: dict, **kw: Any) -> str: async def _slot_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slot-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-slot-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_admin_oob=SxExpr(await _calendar_admin_header_sx(ctx, oob=True)), slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child", @@ -315,11 +315,11 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: # --- Day admin layout (root + post + post-admin + child(cal + day + day-admin)) --- async def _day_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-day-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-day-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -329,11 +329,11 @@ async def _day_admin_full(ctx: dict, **kw: Any) -> str: async def _day_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-day-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-day-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_oob=SxExpr(await _calendar_header_sx(ctx, oob=True)), day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child", @@ -349,9 +349,9 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: # --- Entry layout (root + child(post + cal + day + entry), + menu) --- async def _entry_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-entry-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-entry-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -360,9 +360,9 @@ async def _entry_full(ctx: dict, **kw: Any) -> str: async def _entry_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-entry-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-entry-layout-oob", {}, day_oob=SxExpr(await _day_header_sx(ctx, oob=True)), entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child", "entry-header-child", await _entry_header_html(ctx))), @@ -376,11 +376,11 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: # --- Entry admin layout (root + post + child(post-admin + cal + day + entry + entry-admin), + menu) --- async def _entry_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-entry-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-entry-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -391,11 +391,11 @@ async def _entry_admin_full(ctx: dict, **kw: Any) -> str: async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-entry-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-entry-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), entry_oob=SxExpr(await _entry_header_html(ctx, oob=True)), entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child", @@ -412,9 +412,9 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: # --- Ticket types layout (extends entry admin with ticket-types header, + menu) --- async def _ticket_types_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-types-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-ticket-types-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -425,9 +425,9 @@ async def _ticket_types_full(ctx: dict, **kw: Any) -> str: async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-types-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-ticket-types-layout-oob", {}, entry_admin_oob=SxExpr(await _entry_admin_header_html(ctx, oob=True)), ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child", "ticket_types-header-child", await _ticket_types_header_html(ctx))), @@ -437,9 +437,9 @@ async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: # --- Ticket type detail layout (extends ticket types with ticket-type header, + menu) --- async def _ticket_type_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-type-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-ticket-type-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -451,9 +451,9 @@ async def _ticket_type_full(ctx: dict, **kw: Any) -> str: async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-type-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-ticket-type-layout-oob", {}, ticket_types_oob=SxExpr(await _ticket_types_header_html(ctx, oob=True)), ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child", "ticket_type-header-child", await _ticket_type_header_html(ctx))), @@ -463,18 +463,18 @@ async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: # --- Markets layout (root + child(post + markets)) --- async def _markets_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-markets-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-markets-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), markets_header=SxExpr(await _markets_header_sx(ctx)), ) async def _markets_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-markets-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-markets-layout-oob", {}, post_oob=SxExpr(await _post_header_sx(ctx, oob=True)), markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child", "markets-header-child", await _markets_header_sx(ctx))), diff --git a/events/sxc/pages/layouts.py b/events/sxc/pages/layouts.py index 3532431..82717ab 100644 --- a/events/sxc/pages/layouts.py +++ b/events/sxc/pages/layouts.py @@ -35,11 +35,11 @@ def _register_events_layouts() -> None: # --- Calendar admin layout (root + post + child(post-admin + calendar + cal-admin)) --- async def _cal_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-cal-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-cal-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -48,11 +48,11 @@ async def _cal_admin_full(ctx: dict, **kw: Any) -> str: async def _cal_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-cal-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-cal-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_oob=SxExpr(await _calendar_header_sx(ctx, oob=True)), cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child", @@ -71,11 +71,11 @@ async def _slots_full(ctx: dict, **kw: Any) -> str: async def _slots_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slots-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-slots-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_admin_oob=SxExpr(await _calendar_admin_header_sx(ctx, oob=True)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", @@ -88,11 +88,11 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: # --- Slot detail layout (extends cal-admin with slot header) --- async def _slot_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slot-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-slot-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -102,11 +102,11 @@ async def _slot_full(ctx: dict, **kw: Any) -> str: async def _slot_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav({**ctx, "is_admin_section": True}) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-slot-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-slot-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_admin_oob=SxExpr(await _calendar_admin_header_sx(ctx, oob=True)), slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child", @@ -122,11 +122,11 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: # --- Day admin layout (root + post + post-admin + child(cal + day + day-admin)) --- async def _day_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-day-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-day-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -136,11 +136,11 @@ async def _day_admin_full(ctx: dict, **kw: Any) -> str: async def _day_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-day-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-day-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), cal_oob=SxExpr(await _calendar_header_sx(ctx, oob=True)), day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child", @@ -156,9 +156,9 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: # --- Entry layout (root + child(post + cal + day + entry), + menu) --- async def _entry_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-entry-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-entry-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -167,9 +167,9 @@ async def _entry_full(ctx: dict, **kw: Any) -> str: async def _entry_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-entry-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-entry-layout-oob", {}, day_oob=SxExpr(await _day_header_sx(ctx, oob=True)), entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child", "entry-header-child", await _entry_header_html(ctx))), @@ -183,11 +183,11 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: # --- Entry admin layout (root + post + child(post-admin + cal + day + entry + entry-admin), + menu) --- async def _entry_admin_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-entry-admin-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-entry-admin-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), calendar_header=SxExpr(await _calendar_header_sx(ctx)), @@ -198,11 +198,11 @@ async def _entry_admin_full(ctx: dict, **kw: Any) -> str: async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, post_admin_header_sx, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, post_admin_header_sx, oob_header_sx from shared.sx.parser import SxExpr ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - return await render_to_sx_with_env("events-entry-admin-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-entry-admin-layout-oob", {}, admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), entry_oob=SxExpr(await _entry_header_html(ctx, oob=True)), entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child", @@ -219,9 +219,9 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: # --- Ticket types layout (extends entry admin with ticket-types header, + menu) --- async def _ticket_types_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-types-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-ticket-types-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -232,9 +232,9 @@ async def _ticket_types_full(ctx: dict, **kw: Any) -> str: async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-types-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-ticket-types-layout-oob", {}, entry_admin_oob=SxExpr(await _entry_admin_header_html(ctx, oob=True)), ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child", "ticket_types-header-child", await _ticket_types_header_html(ctx))), @@ -244,9 +244,9 @@ async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: # --- Ticket type detail layout (extends ticket types with ticket-type header, + menu) --- async def _ticket_type_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-type-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-ticket-type-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), calendar_header=SxExpr(await _calendar_header_sx(ctx)), day_header=SxExpr(await _day_header_sx(ctx)), @@ -258,9 +258,9 @@ async def _ticket_type_full(ctx: dict, **kw: Any) -> str: async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-ticket-type-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-ticket-type-layout-oob", {}, ticket_types_oob=SxExpr(await _ticket_types_header_html(ctx, oob=True)), ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child", "ticket_type-header-child", await _ticket_type_header_html(ctx))), @@ -270,18 +270,18 @@ async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: # --- Markets layout (root + child(post + markets)) --- async def _markets_full(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env + from shared.sx.helpers import render_to_sx_with_env from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-markets-layout-full", _ctx_to_env(ctx), + return await render_to_sx_with_env("events-markets-layout-full", {}, post_header=SxExpr(await _post_header_sx(ctx)), markets_header=SxExpr(await _markets_header_sx(ctx)), ) async def _markets_oob(ctx: dict, **kw: Any) -> str: - from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env, oob_header_sx + from shared.sx.helpers import render_to_sx_with_env, oob_header_sx from shared.sx.parser import SxExpr - return await render_to_sx_with_env("events-markets-layout-oob", _ctx_to_env(ctx, oob=True), + return await render_to_sx_with_env("events-markets-layout-oob", {}, post_oob=SxExpr(await _post_header_sx(ctx, oob=True)), markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child", "markets-header-child", await _markets_header_sx(ctx))), diff --git a/events/sxc/pages/renders.py b/events/sxc/pages/renders.py index 8dbd156..1684fc6 100644 --- a/events/sxc/pages/renders.py +++ b/events/sxc/pages/renders.py @@ -2,7 +2,7 @@ from __future__ import annotations from shared.sx.helpers import ( - render_to_sx_with_env, _ctx_to_env, + render_to_sx_with_env, post_admin_header_sx, oob_header_sx, header_child_sx, full_page_sx, oob_page_sx, ) @@ -44,7 +44,7 @@ async def render_all_events_page(ctx: dict, entries, has_more, pending_tickets, ctx, entries, has_more, pending_tickets, page_info, page, view, ticket_url, next_url, events_url, ) - hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + hdr = await render_to_sx_with_env("layout-root-full", {}) return await full_page_sx(ctx, header_rows=hdr, content=content) @@ -105,7 +105,7 @@ async def render_page_summary_page(ctx: dict, entries, has_more, pending_tickets is_page_scoped=True, post=post, ) - hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + hdr = await render_to_sx_with_env("layout-root-full", {}) hdr += await header_child_sx(await _post_header_sx(ctx)) return await full_page_sx(ctx, header_rows=hdr, content=content) @@ -160,7 +160,7 @@ async def render_calendars_page(ctx: dict) -> str: content = await _calendars_main_panel_sx(ctx) ctx = await _ensure_container_nav(ctx) slug = (ctx.get("post") or {}).get("slug", "") - root_hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + root_hdr = await render_to_sx_with_env("layout-root-full", {}) post_hdr = await _post_header_sx(ctx) admin_hdr = await post_admin_header_sx(ctx, slug, selected="calendars") return await full_page_sx(ctx, header_rows=root_hdr + post_hdr + admin_hdr, content=content) @@ -184,7 +184,7 @@ async def render_calendars_oob(ctx: dict) -> str: async def render_calendar_page(ctx: dict) -> str: """Full page: calendar month view.""" content = await _calendar_main_panel_html(ctx) - hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + hdr = await render_to_sx_with_env("layout-root-full", {}) child = await _post_header_sx(ctx) + await _calendar_header_sx(ctx) hdr += await header_child_sx(child) return await full_page_sx(ctx, header_rows=hdr, content=content) @@ -208,7 +208,7 @@ async def render_calendar_oob(ctx: dict) -> str: async def render_day_page(ctx: dict) -> str: """Full page: day detail.""" content = await _day_main_panel_html(ctx) - hdr = await render_to_sx_with_env("layout-root-full", _ctx_to_env(ctx)) + hdr = await render_to_sx_with_env("layout-root-full", {}) child = (await _post_header_sx(ctx) + await _calendar_header_sx(ctx) + await _day_header_sx(ctx)) hdr += await header_child_sx(child) diff --git a/events/sxc/pages/slots.py b/events/sxc/pages/slots.py index f9a2db4..b3ad565 100644 --- a/events/sxc/pages/slots.py +++ b/events/sxc/pages/slots.py @@ -1,7 +1,6 @@ """Slot panels, forms, edit/add, slot picker JS.""" from __future__ import annotations -from markupsafe import escape from shared.sx.helpers import render_to_sx from shared.sx.parser import SxExpr @@ -156,20 +155,12 @@ async def _slot_header_html(ctx: dict, *, oob: bool = False) -> str: if not slot: return "" - # Label: icon + name + description desc = getattr(slot, "description", "") or "" - label_inner = ( - f'
{escape(desc)}
' - f'