diff --git a/account/sx/handlers/auth-menu.sx b/account/sx/handlers/auth-menu.sx index 28d4c02..16d93b4 100644 --- a/account/sx/handlers/auth-menu.sx +++ b/account/sx/handlers/auth-menu.sx @@ -1,4 +1,5 @@ ;; Account auth-menu fragment handler +;; returns: sx ;; ;; Renders the desktop + mobile auth menu (sign-in or user link). diff --git a/blog/bp/menu_items/routes.py b/blog/bp/menu_items/routes.py index 48c3117..d9a75be 100644 --- a/blog/bp/menu_items/routes.py +++ b/blog/bp/menu_items/routes.py @@ -144,7 +144,7 @@ def _render_page_search_results(pages, query, page, has_more) -> str: items_sx = "(<> " + " ".join(items) + ")" return sx_call("page-search-results", items=SxExpr(items_sx), - sentinel=SxExpr(sentinel) if sentinel else None) + sentinel=sentinel or None) def _render_menu_items_nav_oob(menu_items) -> str: @@ -191,12 +191,12 @@ def _render_menu_items_nav_oob(menu_items) -> str: if item_slug != "cart": item_parts.append(sx_call("blog-nav-item-link", href=href, hx_get=f"/{item_slug}/", selected=selected, - nav_cls=nav_button_cls, img=SxExpr(img_sx), label=label, + nav_cls=nav_button_cls, img=img_sx, label=label, )) else: item_parts.append(sx_call("blog-nav-item-plain", href=href, selected=selected, nav_cls=nav_button_cls, - img=SxExpr(img_sx), label=label, + img=img_sx, label=label, )) items_sx = "(<> " + " ".join(item_parts) + ")" if item_parts else "" diff --git a/blog/bp/post/admin/routes.py b/blog/bp/post/admin/routes.py index 9828f48..8823bfa 100644 --- a/blog/bp/post/admin/routes.py +++ b/blog/bp/post/admin/routes.py @@ -226,7 +226,7 @@ def _render_associated_entries(all_calendars, associated_entry_ids, post_slug: s confirm_text=f"This will remove {e_name} from this post", toggle_url=toggle_url, hx_headers=f'{{"X-CSRFToken": "{csrf}"}}', - img=SxExpr(img_sx), name=e_name, + img=img_sx, name=e_name, date_str=f"{cal_name} \u2022 {date_str}", )) @@ -237,7 +237,7 @@ def _render_associated_entries(all_calendars, associated_entry_ids, post_slug: s else: content_sx = sx_call("blog-associated-entries-empty") - return sx_call("blog-associated-entries-panel", content=SxExpr(content_sx)) + return sx_call("blog-associated-entries-panel", content=content_sx) def _render_nav_entries_oob(associated_entries, calendars, post: dict) -> str: diff --git a/blog/sx/handlers/link-card.sx b/blog/sx/handlers/link-card.sx index 8598a6b..bdc26ae 100644 --- a/blog/sx/handlers/link-card.sx +++ b/blog/sx/handlers/link-card.sx @@ -1,4 +1,5 @@ ;; Blog link-card fragment handler +;; returns: sx ;; ;; Renders link-card(s) for blog posts by slug. ;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z). diff --git a/blog/sx/handlers/nav-tree.sx b/blog/sx/handlers/nav-tree.sx index 3d10625..72a54b4 100644 --- a/blog/sx/handlers/nav-tree.sx +++ b/blog/sx/handlers/nav-tree.sx @@ -1,4 +1,5 @@ ;; Blog nav-tree fragment handler +;; returns: sx ;; ;; Renders the full scrollable navigation menu bar with app icons. ;; Uses nav-tree I/O primitive to fetch menu nodes from the blog DB. diff --git a/blog/sxc/pages/helpers.py b/blog/sxc/pages/helpers.py index 9e2e2b8..7647db4 100644 --- a/blog/sxc/pages/helpers.py +++ b/blog/sxc/pages/helpers.py @@ -279,11 +279,11 @@ async def _h_post_preview_content(slug=None, **kw): if preview.get("sx_rendered"): rendered_sx = sx_call("blog-preview-rendered", html=preview["sx_rendered"]) sections.append(sx_call("blog-preview-section", - title="SX Rendered", content=SxExpr(rendered_sx))) + title="SX Rendered", content=rendered_sx)) if preview.get("lex_rendered"): rendered_sx = sx_call("blog-preview-rendered", html=preview["lex_rendered"]) sections.append(sx_call("blog-preview-section", - title="Lexical Rendered", content=SxExpr(rendered_sx))) + title="Lexical Rendered", content=rendered_sx)) if not sections: return sx_call("blog-preview-empty") diff --git a/blog/sxc/pages/layouts.py b/blog/sxc/pages/layouts.py index 002fbbd..15dfb6e 100644 --- a/blog/sxc/pages/layouts.py +++ b/blog/sxc/pages/layouts.py @@ -10,7 +10,6 @@ from typing import Any def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str: from shared.sx.helpers import sx_call - from shared.sx.parser import SxExpr from quart import url_for as qurl settings_href = qurl("settings.defpage_settings_home") @@ -20,8 +19,8 @@ def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str: return sx_call("menu-row-sx", id="root-settings-row", level=1, link_href=settings_href, - link_label_content=SxExpr(label_sx), - nav=SxExpr(nav_sx) if nav_sx else None, + link_label_content=label_sx, + nav=nav_sx or None, child_id="root-settings-header-child", oob=oob) @@ -41,7 +40,7 @@ def _sub_settings_header_sx(row_id: str, child_id: str, href: str, return sx_call("menu-row-sx", id=row_id, level=2, link_href=href, - link_label_content=SxExpr(label_sx), + link_label_content=label_sx, nav=SxExpr(nav_sx) if nav_sx else None, child_id=child_id, oob=oob) @@ -80,16 +79,14 @@ async def _blog_oob(ctx: dict, **kw: Any) -> str: async def _settings_full(ctx: dict, **kw: Any) -> str: 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", {}, - settings_header=SxExpr(_settings_header_sx(ctx))) + settings_header=_settings_header_sx(ctx)) async def _settings_oob(ctx: dict, **kw: Any) -> str: 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", {}, - settings_header=SxExpr(_settings_header_sx(ctx))) + settings_header=_settings_header_sx(ctx)) return await oob_header_sx("root-header-child", "root-settings-header-child", rows) @@ -102,26 +99,24 @@ 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 - from shared.sx.parser import SxExpr from quart import url_for as qurl return await render_to_sx_with_env("sub-settings-layout-full", {}, - settings_header=SxExpr(_settings_header_sx(ctx)), - sub_header=SxExpr(_sub_settings_header_sx( - row_id, child_id, qurl(endpoint), icon, label, ctx))) + settings_header=_settings_header_sx(ctx), + sub_header=_sub_settings_header_sx( + row_id, child_id, qurl(endpoint), icon, label, ctx)) async def _sub_settings_oob(ctx: dict, row_id: str, child_id: str, endpoint: str, icon: str, label: str) -> str: from shared.sx.helpers import oob_header_sx, sx_call - from shared.sx.parser import SxExpr from quart import url_for as qurl settings_hdr_oob = _settings_header_sx(ctx, oob=True) sub_hdr = _sub_settings_header_sx( row_id, child_id, qurl(endpoint), icon, label, ctx) sub_oob = await oob_header_sx("root-settings-header-child", child_id, sub_hdr) return sx_call("sub-settings-layout-oob", - settings_header_oob=SxExpr(settings_hdr_oob), - sub_header_oob=SxExpr(sub_oob)) + settings_header_oob=settings_hdr_oob, + sub_header_oob=sub_oob) # --- Cache --- @@ -177,20 +172,18 @@ 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 - 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", {}, - settings_header=SxExpr(_settings_header_sx(ctx)), - sub_header=SxExpr(_sub_settings_header_sx( + settings_header=_settings_header_sx(ctx), + sub_header=_sub_settings_header_sx( "tag-groups-row", "tag-groups-header-child", qurl("defpage_tag_group_edit", id=g_id), - "tags", "Tag Groups", ctx))) + "tags", "Tag Groups", ctx)) async def _tag_group_edit_oob(ctx: dict, **kw: Any) -> str: from quart import request, url_for as qurl from shared.sx.helpers import oob_header_sx, sx_call - from shared.sx.parser import SxExpr g_id = (request.view_args or {}).get("id") settings_hdr_oob = _settings_header_sx(ctx, oob=True) sub_hdr = _sub_settings_header_sx( @@ -199,5 +192,5 @@ async def _tag_group_edit_oob(ctx: dict, **kw: Any) -> str: "tags", "Tag Groups", ctx) sub_oob = await oob_header_sx("root-settings-header-child", "tag-groups-header-child", sub_hdr) return sx_call("sub-settings-layout-oob", - settings_header_oob=SxExpr(settings_hdr_oob), - sub_header_oob=SxExpr(sub_oob)) + settings_header_oob=settings_hdr_oob, + sub_header_oob=sub_oob) diff --git a/cart/sx/handlers/account-nav-item.sx b/cart/sx/handlers/account-nav-item.sx index 5c31f44..c939a69 100644 --- a/cart/sx/handlers/account-nav-item.sx +++ b/cart/sx/handlers/account-nav-item.sx @@ -1,4 +1,5 @@ ;; Cart account-nav-item fragment handler +;; returns: sx ;; ;; Renders the "orders" link for the account dashboard nav. diff --git a/cart/sx/handlers/cart-mini.sx b/cart/sx/handlers/cart-mini.sx index 2dbb44a..87e9a75 100644 --- a/cart/sx/handlers/cart-mini.sx +++ b/cart/sx/handlers/cart-mini.sx @@ -1,4 +1,5 @@ ;; Cart cart-mini fragment handler +;; returns: sx ;; ;; Renders the cart icon with badge (or logo when empty). diff --git a/cart/sxc/pages/layouts.py b/cart/sxc/pages/layouts.py index 536257f..c7b7de8 100644 --- a/cart/sxc/pages/layouts.py +++ b/cart/sxc/pages/layouts.py @@ -3,8 +3,6 @@ from __future__ import annotations from typing import Any -from shared.sx.parser import SxExpr - def _register_cart_layouts() -> None: from shared.sx.layouts import register_custom_layout @@ -80,8 +78,8 @@ def _page_cart_header_sx(ctx: dict, page_post: Any, *, oob: bool = False) -> str "menu-row-sx", id="page-cart-row", level=2, colour="sky", link_href=call_url(ctx, "cart_url", f"/{slug}/"), - link_label_content=SxExpr(label_sx), - nav=SxExpr(nav_sx), oob=oob, + link_label_content=label_sx, + nav=nav_sx, oob=oob, ) @@ -102,8 +100,8 @@ async def _cart_page_full(ctx: dict, **kw: Any) -> str: page_post = ctx.get("page_post") env = {} return await render_to_sx_with_env("cart-page-layout-full", env, - cart_row=SxExpr(_cart_header_sx(ctx)), - page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)), + cart_row=_cart_header_sx(ctx), + page_cart_row=_page_cart_header_sx(ctx, page_post), ) @@ -112,9 +110,9 @@ async def _cart_page_oob(ctx: dict, **kw: Any) -> str: page_post = ctx.get("page_post") 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(_cart_header_sx(ctx, oob=True)), - page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)), + root_header_oob=await root_header_sx(ctx, oob=True), + cart_row_oob=_cart_header_sx(ctx, oob=True), + page_cart_row=_page_cart_header_sx(ctx, page_post), ) @@ -124,8 +122,8 @@ async def _cart_admin_full(ctx: dict, **kw: Any) -> str: selected = kw.get("selected", "") 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)), + post_header=await _post_header_sx(ctx, page_post), + admin_header=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 f4f0f98..6237a81 100644 --- a/cart/sxc/pages/renders.py +++ b/cart/sxc/pages/renders.py @@ -20,7 +20,7 @@ async def render_orders_page(ctx, orders, page, total_pages, search, search_coun header_rows = await render_to_sx_with_env("cart-orders-layout-full", {}, list_url=list_url, ) - filt = sx_call("order-list-header", search_mobile=SxExpr(await search_mobile_sx(ctx))) + filt = sx_call("order-list-header", search_mobile=await search_mobile_sx(ctx)) return await full_page_sx(ctx, header_rows=header_rows, filter=filt, aside=await search_desktop_sx(ctx), content=content) @@ -44,7 +44,7 @@ def render_orders_rows(ctx, orders, page, total_pages, url_for_fn, qs_fn): next_scroll = sx_call("order-end-row") return sx_call("cart-orders-rows", rows=SxExpr("(<> " + " ".join(parts) + ")"), - next_scroll=SxExpr(next_scroll), + next_scroll=next_scroll, ) @@ -62,7 +62,7 @@ async def render_orders_oob(ctx, orders, page, total_pages, search, search_count oobs = await render_to_sx_with_env("cart-orders-layout-oob", {}, list_url=list_url, ) - filt = sx_call("order-list-header", search_mobile=SxExpr(await search_mobile_sx(ctx))) + filt = sx_call("order-list-header", search_mobile=await search_mobile_sx(ctx)) return await oob_page_sx(oobs=oobs, filter=filt, aside=await search_desktop_sx(ctx), content=content) @@ -116,7 +116,7 @@ async def render_checkout_error_page(ctx, error=None, order=None): hdr = await render_to_sx_with_env("layout-root-full", {}) filt = sx_call("checkout-error-header") content = sx_call("checkout-error-content", msg=err_msg, - order=SxExpr(order_sx) if order_sx else None, back_url=cart_url("/")) + order=order_sx or None, back_url=cart_url("/")) return await full_page_sx(ctx, header_rows=hdr, filter=filt, content=content) diff --git a/events/sx/handlers/account-nav-item.sx b/events/sx/handlers/account-nav-item.sx index 73f248c..e3c8881 100644 --- a/events/sx/handlers/account-nav-item.sx +++ b/events/sx/handlers/account-nav-item.sx @@ -1,4 +1,5 @@ ;; Events account-nav-item fragment handler +;; returns: sx ;; ;; Renders tickets + bookings links for the account dashboard nav. diff --git a/events/sx/handlers/account-page.sx b/events/sx/handlers/account-page.sx index 925eb8c..b0b5893 100644 --- a/events/sx/handlers/account-page.sx +++ b/events/sx/handlers/account-page.sx @@ -1,4 +1,5 @@ ;; Account-page fragment handler +;; returns: sx ;; ;; Renders tickets or bookings panel for the account dashboard. ;; slug=tickets → ticket list; slug=bookings → booking list. diff --git a/events/sx/handlers/container-cards.sx b/events/sx/handlers/container-cards.sx index 193f23a..7025723 100644 --- a/events/sx/handlers/container-cards.sx +++ b/events/sx/handlers/container-cards.sx @@ -1,4 +1,5 @@ ;; Container-cards fragment handler +;; returns: sx ;; ;; Returns HTML with comment markers so the ;; blog consumer can split per-post fragments. Each post section diff --git a/events/sx/handlers/container-nav.sx b/events/sx/handlers/container-nav.sx index d58f9fb..7bb41e9 100644 --- a/events/sx/handlers/container-nav.sx +++ b/events/sx/handlers/container-nav.sx @@ -1,4 +1,5 @@ ;; Events container-nav fragment handler +;; returns: sx ;; ;; Renders calendar entry nav items + calendar link nav items ;; for the scrollable navigation panel on blog post pages. diff --git a/events/sx/handlers/link-card.sx b/events/sx/handlers/link-card.sx index 1c58552..630eead 100644 --- a/events/sx/handlers/link-card.sx +++ b/events/sx/handlers/link-card.sx @@ -1,4 +1,5 @@ ;; Events link-card fragment handler +;; returns: sx ;; ;; Renders event page preview card(s) by slug. ;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z). diff --git a/events/sxc/pages/calendar.py b/events/sxc/pages/calendar.py index 67d268a..6dacc04 100644 --- a/events/sxc/pages/calendar.py +++ b/events/sxc/pages/calendar.py @@ -78,7 +78,7 @@ def _calendars_header_sx(ctx: dict, *, oob: bool = False) -> str: link_href = url_for("calendars.home") return sx_call("menu-row-sx", id="calendars-row", level=3, link_href=link_href, - link_label_content=SxExpr(sx_call("events-calendars-label")), + link_label_content=sx_call("events-calendars-label"), child_id="calendars-header-child", oob=oob) @@ -104,7 +104,7 @@ def _calendar_header_sx(ctx: dict, *, oob: bool = False) -> str: nav_html = _calendar_nav_sx(ctx) return sx_call("menu-row-sx", id="calendar-row", level=3, - link_href=link_href, link_label_content=SxExpr(label_html), + link_href=link_href, link_label_content=label_html, nav=SxExpr(nav_html) if nav_html else None, child_id="calendar-header-child", oob=oob) @@ -158,7 +158,7 @@ def _day_header_sx(ctx: dict, *, oob: bool = False) -> str: nav_html = _day_nav_sx(ctx) return sx_call("menu-row-sx", id="day-row", level=4, - link_href=link_href, link_label_content=SxExpr(label_html), + link_href=link_href, link_label_content=label_html, nav=SxExpr(nav_html) if nav_html else None, child_id="day-header-child", oob=oob) @@ -271,7 +271,7 @@ def _markets_header_sx(ctx: dict, *, oob: bool = False) -> str: link_href = url_for("defpage_events_markets") return sx_call("menu-row-sx", id="markets-row", level=3, link_href=link_href, - link_label_content=SxExpr(sx_call("events-markets-label")), + link_label_content=sx_call("events-markets-label"), child_id="markets-header-child", oob=oob) @@ -544,7 +544,7 @@ def _day_row_html(ctx: dict, entry) -> str: state = getattr(entry, "state", "pending") or "pending" state_badge = _entry_state_badge_html(state) state_td = sx_call("events-day-row-state", - state_id=f"entry-state-{entry.id}", badge=SxExpr(state_badge)) + state_id=f"entry-state-{entry.id}", badge=state_badge) # Cost cost = getattr(entry, "cost", None) @@ -564,9 +564,9 @@ def _day_row_html(ctx: dict, entry) -> str: actions_td = sx_call("events-day-row-actions") return sx_call("events-day-row", - tr_cls=tr_cls, name=SxExpr(name_html), slot=SxExpr(slot_html), - state=SxExpr(state_td), cost=SxExpr(cost_td), - tickets=SxExpr(tickets_td), actions=SxExpr(actions_td)) + tr_cls=tr_cls, name=name_html, slot=slot_html, + state=state_td, cost=cost_td, + tickets=tickets_td, actions=actions_td) # --------------------------------------------------------------------------- @@ -598,7 +598,7 @@ def _calendar_admin_main_panel_html(ctx: dict) -> str: description_html = _calendar_description_display_html(calendar, desc_edit_url) return sx_call("events-calendar-admin-panel", - description_content=SxExpr(description_html), csrf=csrf, + description_content=description_html, csrf=csrf, description=desc) diff --git a/events/sxc/pages/entries.py b/events/sxc/pages/entries.py index b8cd573..a917885 100644 --- a/events/sxc/pages/entries.py +++ b/events/sxc/pages/entries.py @@ -73,10 +73,10 @@ def _entry_card_html(entry, page_info: dict, pending_tickets: dict, if tp is not None: qty = pending_tickets.get(entry.id, 0) widget_html = sx_call("events-entry-widget-wrapper", - widget=SxExpr(_ticket_widget_html(entry, qty, ticket_url, ctx={}))) + widget=_ticket_widget_html(entry, qty, ticket_url, ctx={})) return sx_call("events-entry-card", - title=SxExpr(title_html), badges=SxExpr(badges_html), + title=title_html, badges=SxExpr(badges_html), time_parts=SxExpr(time_parts), cost=SxExpr(cost_html), widget=SxExpr(widget_html)) @@ -137,10 +137,10 @@ def _entry_card_tile_html(entry, page_info: dict, pending_tickets: dict, if tp is not None: qty = pending_tickets.get(entry.id, 0) widget_html = sx_call("events-entry-tile-widget-wrapper", - widget=SxExpr(_ticket_widget_html(entry, qty, ticket_url, ctx={}))) + widget=_ticket_widget_html(entry, qty, ticket_url, ctx={})) return sx_call("events-entry-card-tile", - title=SxExpr(title_html), badges=SxExpr(badges_html), + title=title_html, badges=SxExpr(badges_html), time=SxExpr(time_html), cost=SxExpr(cost_html), widget=SxExpr(widget_html)) @@ -199,7 +199,7 @@ def _events_main_panel_html(ctx: dict, entries, has_more, pending_tickets, page_ cls="px-3 py-12 text-center text-stone-400") return sx_call("events-main-panel-body", - toggle=SxExpr(toggle), body=SxExpr(body)) + toggle=toggle, body=body) # --------------------------------------------------------------------------- @@ -253,7 +253,7 @@ def _entry_main_panel_html(ctx: dict) -> str: # State state_html = _field("State", sx_call("events-entry-state-field", entry_id=str(eid), - badge=SxExpr(_entry_state_badge_html(state)))) + badge=_entry_state_badge_html(state))) # Cost cost = getattr(entry, "cost", None) @@ -284,7 +284,7 @@ def _entry_main_panel_html(ctx: dict) -> str: entry_posts = ctx.get("entry_posts") or [] posts_html = _field("Associated Posts", sx_call("events-entry-posts-field", entry_id=str(eid), - posts_panel=SxExpr(render_entry_posts_panel(entry_posts, entry, calendar, day, month, year)))) + posts_panel=render_entry_posts_panel(entry_posts, entry, calendar, day, month, year))) # Options and Edit Button edit_url = url_for( @@ -295,12 +295,12 @@ def _entry_main_panel_html(ctx: dict) -> str: return sx_call("events-entry-panel", entry_id=str(eid), list_container=list_container, - name=SxExpr(name_html), slot=SxExpr(slot_html), - time=SxExpr(time_html), state=SxExpr(state_html), - cost=SxExpr(cost_html), tickets=SxExpr(tickets_html), - buy=SxExpr(buy_html), date=SxExpr(date_html), - posts=SxExpr(posts_html), - options=SxExpr(_entry_options_html(entry, calendar, day, month, year)), + name=name_html, slot=slot_html, + time=time_html, state=state_html, + cost=cost_html, tickets=tickets_html, + buy=SxExpr(buy_html), date=date_html, + posts=posts_html, + options=_entry_options_html(entry, calendar, day, month, year), pre_action=pre_action, edit_url=edit_url) @@ -331,13 +331,13 @@ def _entry_header_html(ctx: dict, *, oob: bool = False) -> str: ) label_html = sx_call("events-entry-label", entry_id=str(entry.id), - title=SxExpr(_entry_title_html(entry)), + title=_entry_title_html(entry), times=SxExpr(_entry_times_html(entry))) nav_html = _entry_nav_html(ctx) return sx_call("menu-row-sx", id="entry-row", level=5, - link_href=link_href, link_label_content=SxExpr(label_html), + link_href=link_href, link_label_content=label_html, nav=SxExpr(nav_html) if nav_html else None, child_id="entry-header-child", oob=oob) @@ -391,7 +391,7 @@ def _entry_nav_html(ctx: dict) -> str: else: img_html = sx_call("events-post-img-placeholder") post_links += sx_call("events-entry-nav-post-link", - href=href, img=SxExpr(img_html), title=title) + href=href, img=img_html, title=title) parts.append((sx_call("events-entry-posts-nav-oob", items=SxExpr(post_links))).replace(' :hx-swap-oob "true"', '')) @@ -420,7 +420,7 @@ def render_entry_optioned(entry, calendar, day, month, year) -> str: return options + sx_call("events-entry-optioned-oob", entry_id=str(entry.id), - title=SxExpr(title), state=SxExpr(state)) + title=title, state=state) def _entry_title_html(entry) -> str: @@ -428,7 +428,7 @@ def _entry_title_html(entry) -> str: state = getattr(entry, "state", "pending") or "pending" return sx_call("events-entry-title", name=entry.name, - badge=SxExpr(_entry_state_badge_html(state))) + badge=_entry_state_badge_html(state)) def _entry_options_html(entry, calendar, day, month, year) -> str: @@ -550,7 +550,7 @@ def render_entry_posts_panel(entry_posts, entry, calendar, day, month, year) -> entry_id=eid, post_id=ep_id, ) items += sx_call("events-entry-post-item", - img=SxExpr(img_html), title=ep_title, + img=img_html, title=ep_title, del_url=del_url, entry_id=eid_s, csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}') posts_html = sx_call("events-entry-posts-list", items=SxExpr(items)) @@ -563,7 +563,7 @@ def render_entry_posts_panel(entry_posts, entry, calendar, day, month, year) -> ) return sx_call("events-entry-posts-panel", - posts=SxExpr(posts_html), search_url=search_url, + posts=posts_html, search_url=search_url, entry_id=eid_s) @@ -591,7 +591,7 @@ def render_entry_posts_nav_oob(entry_posts) -> str: if feat else sx_call("events-post-img-placeholder")) items += sx_call("events-entry-nav-post", href=href, nav_btn=nav_btn, - img=SxExpr(img_html), title=title) + img=img_html, title=title) return sx_call("events-entry-posts-nav-oob", items=SxExpr(items)) @@ -743,7 +743,7 @@ def _entry_admin_header_html(ctx: dict, *, oob: bool = False) -> str: return sx_call("menu-row-sx", id="entry-admin-row", level=6, link_href=link_href, link_label="admin", icon="fa fa-cog", - nav=SxExpr(nav_html) if nav_html else None, child_id="entry-admin-header-child", oob=oob) + nav=nav_html or None, child_id="entry-admin-header-child", oob=oob) def _entry_admin_nav_html(ctx: dict) -> str: @@ -822,7 +822,7 @@ def render_post_search_results(search_posts, search_query, page, total_pages, parts.append(sx_call("events-post-search-item", post_url=post_url, entry_id=str(eid), csrf=csrf, - post_id=str(sp.id), img=SxExpr(img_html), title=title)) + post_id=str(sp.id), img=img_html, title=title)) result = "".join(parts) @@ -882,7 +882,7 @@ def render_entry_edit_form(entry, calendar, day, month, year, day_slots) -> str: html = sx_call("events-entry-edit-form", entry_id=str(eid), list_container=list_container, put_url=put_url, cancel_url=cancel_url, csrf=csrf, - name_val=entry.name or "", slot_picker=SxExpr(slot_picker_html), + name_val=entry.name or "", slot_picker=slot_picker_html, start_val=start_val, end_val=end_val, cost_display=cost_display, ticket_price_val=tp_val, ticket_count_val=tc_val, action_btn=action_btn, cancel_btn=cancel_btn) @@ -920,7 +920,7 @@ def render_entry_add_form(calendar, day, month, year, day_slots) -> str: html = sx_call("events-entry-add-form", post_url=post_url, csrf=csrf, - slot_picker=SxExpr(slot_picker_html), + slot_picker=slot_picker_html, action_btn=action_btn, cancel_btn=cancel_btn, cancel_url=cancel_url) return html + _SLOT_PICKER_JS @@ -998,13 +998,13 @@ def render_fragment_account_tickets(tickets) -> str: items_html += sx_call("events-frag-ticket-item", href=href, entry_name=ticket.entry_name, date_str=date_str, calendar_name=cal_name, - type_name=type_name, badge=SxExpr(badge_html)) + type_name=type_name, badge=badge_html) body = sx_call("events-frag-tickets-list", items=SxExpr(items_html)) else: body = sx_call("empty-state", message="No tickets yet.", cls="text-sm text-stone-500") - return sx_call("events-frag-tickets-panel", items=SxExpr(body)) + return sx_call("events-frag-tickets-panel", items=body) # --------------------------------------------------------------------------- @@ -1033,10 +1033,10 @@ def render_fragment_account_bookings(bookings) -> str: name=booking.name, date_str=date_str + date_str_extra, calendar_name=cal_name, cost_str=cost_str, - badge=SxExpr(badge_html)) + badge=badge_html) body = sx_call("events-frag-bookings-list", items=SxExpr(items_html)) else: body = sx_call("empty-state", message="No bookings yet.", cls="text-sm text-stone-500") - return sx_call("events-frag-bookings-panel", items=SxExpr(body)) + return sx_call("events-frag-bookings-panel", items=body) diff --git a/events/sxc/pages/helpers.py b/events/sxc/pages/helpers.py index ddf8dab..37e491f 100644 --- a/events/sxc/pages/helpers.py +++ b/events/sxc/pages/helpers.py @@ -229,14 +229,13 @@ def _register_events_layouts() -> None: async def _cal_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + calendar_admin_header=_calendar_admin_header_sx(ctx), ) @@ -246,10 +245,10 @@ async def _cal_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)), - cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child", - "calendar-admin-header-child", _calendar_admin_header_sx(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_oob=_calendar_header_sx(ctx, oob=True), + cal_admin_oob_wrap=await oob_header_sx("calendar-header-child", + "calendar-admin-header-child", _calendar_admin_header_sx(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -269,8 +268,8 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -282,15 +281,14 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: async def _slot_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)), - slot_header=SxExpr(_slot_header_html(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + calendar_admin_header=_calendar_admin_header_sx(ctx), + slot_header=_slot_header_html(ctx), ) @@ -300,10 +298,10 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)), - slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child", - "slot-header-child", _slot_header_html(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True), + slot_oob_wrap=await oob_header_sx("calendar-admin-header-child", + "slot-header-child", _slot_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -316,15 +314,14 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: async def _day_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - day_admin_header=SxExpr(_day_admin_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + day_admin_header=_day_admin_header_sx(ctx), ) @@ -334,10 +331,10 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)), - day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child", - "day-admin-header-child", _day_admin_header_sx(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_oob=_calendar_header_sx(ctx, oob=True), + day_admin_oob_wrap=await oob_header_sx("day-header-child", + "day-admin-header-child", _day_admin_header_sx(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -350,12 +347,11 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: async def _entry_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), ) @@ -363,9 +359,9 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: 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", {}, - day_oob=SxExpr(_day_header_sx(ctx, oob=True)), - entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child", - "entry-header-child", _entry_header_html(ctx))), + day_oob=_day_header_sx(ctx, oob=True), + entry_oob_wrap=await oob_header_sx("day-header-child", + "entry-header-child", _entry_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "calendar-row", "calendar-header-child", "day-row", "day-header-child", @@ -377,16 +373,15 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: async def _entry_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), ) @@ -396,10 +391,10 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - entry_oob=SxExpr(_entry_header_html(ctx, oob=True)), - entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child", - "entry-admin-header-child", _entry_admin_header_html(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + entry_oob=_entry_header_html(ctx, oob=True), + entry_admin_oob_wrap=await oob_header_sx("entry-header-child", + "entry-admin-header-child", _entry_admin_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -413,24 +408,22 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: async def _ticket_types_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), - ticket_types_header=SxExpr(_ticket_types_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), + ticket_types_header=_ticket_types_header_html(ctx), ) async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: 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", {}, - entry_admin_oob=SxExpr(_entry_admin_header_html(ctx, oob=True)), - ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child", - "ticket_types-header-child", _ticket_types_header_html(ctx))), + entry_admin_oob=_entry_admin_header_html(ctx, oob=True), + ticket_types_oob_wrap=await oob_header_sx("entry-admin-header-child", + "ticket_types-header-child", _ticket_types_header_html(ctx)), ) @@ -438,25 +431,23 @@ async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: async def _ticket_type_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), - ticket_types_header=SxExpr(_ticket_types_header_html(ctx)), - ticket_type_header=SxExpr(_ticket_type_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), + ticket_types_header=_ticket_types_header_html(ctx), + ticket_type_header=_ticket_type_header_html(ctx), ) async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: 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", {}, - ticket_types_oob=SxExpr(_ticket_types_header_html(ctx, oob=True)), - ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child", - "ticket_type-header-child", _ticket_type_header_html(ctx))), + ticket_types_oob=_ticket_types_header_html(ctx, oob=True), + ticket_type_oob_wrap=await oob_header_sx("ticket_types-header-child", + "ticket_type-header-child", _ticket_type_header_html(ctx)), ) @@ -464,20 +455,18 @@ async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: async def _markets_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - markets_header=SxExpr(_markets_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + markets_header=_markets_header_sx(ctx), ) async def _markets_oob(ctx: dict, **kw: Any) -> str: 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", {}, - post_oob=SxExpr(await _post_header_sx(ctx, oob=True)), - markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child", - "markets-header-child", _markets_header_sx(ctx))), + post_oob=await _post_header_sx(ctx, oob=True), + markets_oob_wrap=await oob_header_sx("post-header-child", + "markets-header-child", _markets_header_sx(ctx)), ) diff --git a/events/sxc/pages/layouts.py b/events/sxc/pages/layouts.py index 5ebe088..1f9345b 100644 --- a/events/sxc/pages/layouts.py +++ b/events/sxc/pages/layouts.py @@ -36,14 +36,13 @@ def _register_events_layouts() -> None: async def _cal_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + calendar_admin_header=_calendar_admin_header_sx(ctx), ) @@ -53,10 +52,10 @@ async def _cal_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)), - cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child", - "calendar-admin-header-child", _calendar_admin_header_sx(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_oob=_calendar_header_sx(ctx, oob=True), + cal_admin_oob_wrap=await oob_header_sx("calendar-header-child", + "calendar-admin-header-child", _calendar_admin_header_sx(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -76,8 +75,8 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -89,15 +88,14 @@ async def _slots_oob(ctx: dict, **kw: Any) -> str: async def _slot_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)), - slot_header=SxExpr(_slot_header_html(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + calendar_admin_header=_calendar_admin_header_sx(ctx), + slot_header=_slot_header_html(ctx), ) @@ -107,10 +105,10 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)), - slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child", - "slot-header-child", _slot_header_html(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True), + slot_oob_wrap=await oob_header_sx("calendar-admin-header-child", + "slot-header-child", _slot_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -123,15 +121,14 @@ async def _slot_oob(ctx: dict, **kw: Any) -> str: async def _day_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - day_admin_header=SxExpr(_day_admin_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + day_admin_header=_day_admin_header_sx(ctx), ) @@ -141,10 +138,10 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)), - day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child", - "day-admin-header-child", _day_admin_header_sx(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + cal_oob=_calendar_header_sx(ctx, oob=True), + day_admin_oob_wrap=await oob_header_sx("day-header-child", + "day-admin-header-child", _day_admin_header_sx(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -157,12 +154,11 @@ async def _day_admin_oob(ctx: dict, **kw: Any) -> str: async def _entry_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), ) @@ -170,9 +166,9 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: 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", {}, - day_oob=SxExpr(_day_header_sx(ctx, oob=True)), - entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child", - "entry-header-child", _entry_header_html(ctx))), + day_oob=_day_header_sx(ctx, oob=True), + entry_oob_wrap=await oob_header_sx("day-header-child", + "entry-header-child", _entry_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "calendar-row", "calendar-header-child", "day-row", "day-header-child", @@ -184,16 +180,15 @@ async def _entry_oob(ctx: dict, **kw: Any) -> str: async def _entry_admin_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), + post_header=await _post_header_sx(ctx), + admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), ) @@ -203,10 +198,10 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: 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", {}, - admin_oob=SxExpr(await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")), - entry_oob=SxExpr(_entry_header_html(ctx, oob=True)), - entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child", - "entry-admin-header-child", _entry_admin_header_html(ctx))), + admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"), + entry_oob=_entry_header_html(ctx, oob=True), + entry_admin_oob_wrap=await oob_header_sx("entry-header-child", + "entry-admin-header-child", _entry_admin_header_html(ctx)), clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child", "post-admin-row", "post-admin-header-child", "calendar-row", "calendar-header-child", @@ -220,24 +215,22 @@ async def _entry_admin_oob(ctx: dict, **kw: Any) -> str: async def _ticket_types_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), - ticket_types_header=SxExpr(_ticket_types_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), + ticket_types_header=_ticket_types_header_html(ctx), ) async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: 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", {}, - entry_admin_oob=SxExpr(_entry_admin_header_html(ctx, oob=True)), - ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child", - "ticket_types-header-child", _ticket_types_header_html(ctx))), + entry_admin_oob=_entry_admin_header_html(ctx, oob=True), + ticket_types_oob_wrap=await oob_header_sx("entry-admin-header-child", + "ticket_types-header-child", _ticket_types_header_html(ctx)), ) @@ -245,25 +238,23 @@ async def _ticket_types_oob(ctx: dict, **kw: Any) -> str: async def _ticket_type_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - calendar_header=SxExpr(_calendar_header_sx(ctx)), - day_header=SxExpr(_day_header_sx(ctx)), - entry_header=SxExpr(_entry_header_html(ctx)), - entry_admin_header=SxExpr(_entry_admin_header_html(ctx)), - ticket_types_header=SxExpr(_ticket_types_header_html(ctx)), - ticket_type_header=SxExpr(_ticket_type_header_html(ctx)), + post_header=await _post_header_sx(ctx), + calendar_header=_calendar_header_sx(ctx), + day_header=_day_header_sx(ctx), + entry_header=_entry_header_html(ctx), + entry_admin_header=_entry_admin_header_html(ctx), + ticket_types_header=_ticket_types_header_html(ctx), + ticket_type_header=_ticket_type_header_html(ctx), ) async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: 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", {}, - ticket_types_oob=SxExpr(_ticket_types_header_html(ctx, oob=True)), - ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child", - "ticket_type-header-child", _ticket_type_header_html(ctx))), + ticket_types_oob=_ticket_types_header_html(ctx, oob=True), + ticket_type_oob_wrap=await oob_header_sx("ticket_types-header-child", + "ticket_type-header-child", _ticket_type_header_html(ctx)), ) @@ -271,18 +262,16 @@ async def _ticket_type_oob(ctx: dict, **kw: Any) -> str: async def _markets_full(ctx: dict, **kw: Any) -> str: 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", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - markets_header=SxExpr(_markets_header_sx(ctx)), + post_header=await _post_header_sx(ctx), + markets_header=_markets_header_sx(ctx), ) async def _markets_oob(ctx: dict, **kw: Any) -> str: 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", {}, - post_oob=SxExpr(await _post_header_sx(ctx, oob=True)), - markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child", - "markets-header-child", _markets_header_sx(ctx))), + post_oob=await _post_header_sx(ctx, oob=True), + markets_oob_wrap=await oob_header_sx("post-header-child", + "markets-header-child", _markets_header_sx(ctx)), ) diff --git a/events/sxc/pages/slots.py b/events/sxc/pages/slots.py index 6661a90..a0b2ded 100644 --- a/events/sxc/pages/slots.py +++ b/events/sxc/pages/slots.py @@ -160,7 +160,7 @@ def _slot_header_html(ctx: dict, *, oob: bool = False) -> str: name=slot.name, description=desc) return sx_call("menu-row-sx", id="slot-row", level=5, - link_label_content=SxExpr(label_sx), + link_label_content=label_sx, child_id="slot-header-child", oob=oob) @@ -201,7 +201,7 @@ def render_slot_main_panel(slot, calendar, *, oob: bool = False) -> str: result = sx_call("events-slot-panel", slot_id=sid, list_container=list_container, - days=SxExpr(days_html), + days=days_html, flexible="yes" if flexible else "no", time_str=f"{time_start} \u2014 {time_end}", cost_str=cost_str, @@ -259,7 +259,7 @@ def render_slots_table(slots, calendar) -> str: pill_cls=pill_cls, hx_select=hx_select, slot_name=s.name, description=desc, flexible="yes" if s.flexible else "no", - days=SxExpr(days_html), + days=days_html, time_str=f"{time_start} - {time_end}", cost_str=cost_str, action_btn=action_btn, del_url=del_url, diff --git a/events/sxc/pages/tickets.py b/events/sxc/pages/tickets.py index af8f520..669468c 100644 --- a/events/sxc/pages/tickets.py +++ b/events/sxc/pages/tickets.py @@ -36,7 +36,7 @@ def _ticket_widget_html(entry, qty: int, ticket_url: str, *, ctx: dict) -> str: return sx_call("events-tw-form", ticket_url=ticket_url, target=tgt, csrf=csrf_token_val, entry_id=str(eid), - count_val=str(count_val), btn=SxExpr(btn_html)) + count_val=str(count_val), btn=btn_html) if qty == 0: inner = _tw_form(1, sx_call("events-tw-cart-plus")) @@ -80,7 +80,7 @@ def _tickets_main_panel_html(ctx: dict, tickets: list) -> str: type_name=tt.name if tt else None, time_str=time_str or None, cal_name=cal.name if cal else None, - badge=SxExpr(_ticket_state_badge_html(state)), + badge=_ticket_state_badge_html(state), code_prefix=ticket.code[:8])) cards_html = "".join(ticket_cards) @@ -193,7 +193,7 @@ def _ticket_admin_main_panel_html(ctx: dict, tickets: list, stats: dict) -> str: entry_name=entry.name if entry else "\u2014", date=SxExpr(date_html), type_name=tt.name if tt else "\u2014", - badge=SxExpr(_ticket_state_badge_html(state)), + badge=_ticket_state_badge_html(state), action=SxExpr(action_html)) return sx_call("events-ticket-admin-panel", @@ -238,7 +238,7 @@ def render_checkin_result(success: bool, error: str | None, ticket) -> str: entry_name=entry.name if entry else "\u2014", date=SxExpr(date_html), type_name=tt.name if tt else "\u2014", - badge=SxExpr(_ticket_state_badge_html("checked_in")), + badge=_ticket_state_badge_html("checked_in"), time_str=time_str) @@ -275,7 +275,7 @@ def render_lookup_result(ticket, error: str | None) -> str: if cal: info_html += sx_call("events-lookup-cal", cal_name=cal.name) info_html += sx_call("events-lookup-status", - badge=SxExpr(_ticket_state_badge_html(state)), code=code) + badge=_ticket_state_badge_html(state), code=code) if checked_in_at: info_html += sx_call("events-lookup-checkin-time", date_str=checked_in_at.strftime("%B %d, %Y at %H:%M")) @@ -328,7 +328,7 @@ def render_entry_tickets_admin(entry, tickets: list) -> str: rows_html += sx_call("events-entry-tickets-admin-row", code=code, code_short=code[:12] + "...", type_name=tt.name if tt else "\u2014", - badge=SxExpr(_ticket_state_badge_html(state)), + badge=_ticket_state_badge_html(state), action=SxExpr(action_html)) if tickets: @@ -340,7 +340,7 @@ def render_entry_tickets_admin(entry, tickets: list) -> str: return sx_call("events-entry-tickets-admin-panel", entry_name=entry.name, count_label=f"{count} ticket{suffix}", - body=SxExpr(body_html)) + body=body_html) # --------------------------------------------------------------------------- @@ -519,16 +519,16 @@ def render_buy_form(entry, ticket_remaining, ticket_sold_count, cost_str = f"\u00a3{tt.cost:.2f}" if tt.cost is not None else "\u00a30.00" type_items += sx_call("events-buy-type-item", type_name=tt.name, cost_str=cost_str, - adjust_controls=SxExpr(_ticket_adjust_controls(csrf, adjust_url, target, eid, type_count, ticket_type_id=tt.id))) + adjust_controls=_ticket_adjust_controls(csrf, adjust_url, target, eid, type_count, ticket_type_id=tt.id)) body_html = sx_call("events-buy-types-wrapper", items=SxExpr(type_items)) else: qty = user_ticket_count or 0 body_html = sx_call("events-buy-default", price_str=f"\u00a3{tp:.2f}", - adjust_controls=SxExpr(_ticket_adjust_controls(csrf, adjust_url, target, eid, qty))) + adjust_controls=_ticket_adjust_controls(csrf, adjust_url, target, eid, qty)) return sx_call("events-buy-panel", - entry_id=eid_s, info=SxExpr(info_html), body=SxExpr(body_html)) + entry_id=eid_s, info=SxExpr(info_html), body=body_html) def _ticket_adjust_controls(csrf, adjust_url, target, entry_id, count, *, ticket_type_id=None): @@ -543,8 +543,8 @@ def _ticket_adjust_controls(csrf, adjust_url, target, entry_id, count, *, ticket return sx_call("events-adjust-form", adjust_url=adjust_url, target=target, extra_cls=extra_cls, csrf=csrf, - entry_id=eid_s, tt=SxExpr(tt_html) if tt_html else None, - count_val=str(count_val), btn=SxExpr(btn_html)) + entry_id=eid_s, tt=tt_html or None, + count_val=str(count_val), btn=btn_html) if count == 0: return _adj_form(1, sx_call("events-adjust-cart-plus"), @@ -557,7 +557,7 @@ def _ticket_adjust_controls(csrf, adjust_url, target, entry_id, count, *, ticket plus = _adj_form(count + 1, sx_call("events-adjust-plus")) return sx_call("events-adjust-controls", - minus=SxExpr(minus), cart_icon=SxExpr(cart_icon), plus=SxExpr(plus)) + minus=minus, cart_icon=cart_icon, plus=plus) # --------------------------------------------------------------------------- @@ -603,7 +603,7 @@ def _ticket_types_header_html(ctx: dict, *, oob: bool = False) -> str: return sx_call("menu-row-sx", id="ticket_types-row", level=7, link_href=link_href, link_label_content=SxExpr(label_html), - nav=SxExpr(nav_html) if nav_html else None, child_id="ticket_type-header-child", oob=oob) + nav=nav_html or None, child_id="ticket_type-header-child", oob=oob) @@ -639,7 +639,7 @@ def _ticket_type_header_html(ctx: dict, *, oob: bool = False) -> str: return sx_call("menu-row-sx", id="ticket_type-row", level=8, link_href=link_href, link_label_content=SxExpr(label_html), - nav=SxExpr(nav_html) if nav_html else None, child_id="ticket_type-header-child-inner", oob=oob) + nav=nav_html or None, child_id="ticket_type-header-child-inner", oob=oob) # --------------------------------------------------------------------------- diff --git a/events/sxc/pages/utils.py b/events/sxc/pages/utils.py index 07cbaa8..afd79e6 100644 --- a/events/sxc/pages/utils.py +++ b/events/sxc/pages/utils.py @@ -2,7 +2,6 @@ from __future__ import annotations from shared.sx.helpers import sx_call -from shared.sx.parser import SxExpr # --------------------------------------------------------------------------- @@ -146,7 +145,7 @@ def _view_toggle_html(ctx: dict, view: str) -> str: list_href=list_href, tile_href=tile_href, hx_select=hx_select, list_cls=list_active, tile_cls=tile_active, storage_key="events_view", - list_svg=SxExpr(_get_list_svg()), tile_svg=SxExpr(_get_tile_svg())) + list_svg=_get_list_svg(), tile_svg=_get_tile_svg()) def _cart_icon_oob(count: int) -> str: diff --git a/federation/bp/identity/routes.py b/federation/bp/identity/routes.py index db74ffa..bdc6c1a 100644 --- a/federation/bp/identity/routes.py +++ b/federation/bp/identity/routes.py @@ -31,7 +31,6 @@ async def _render_choose_username(*, actor=None, error="", username=""): from shared.browser.app.csrf import generate_csrf_token from shared.config import config from shared.sx.helpers import sx_call - from shared.sx.parser import SxExpr from shared.sx.page import get_template_context from sxc.pages.utils import _social_page from markupsafe import escape @@ -45,7 +44,7 @@ async def _render_choose_username(*, actor=None, error="", username=""): content = sx_call( "federation-choose-username", domain=str(escape(ap_domain)), - error=SxExpr(error_sx) if error_sx else None, + error=error_sx or None, csrf=csrf, username=str(escape(username)), check_url=check_url, ) diff --git a/federation/bp/social/routes.py b/federation/bp/social/routes.py index 507b9f4..a625a1d 100644 --- a/federation/bp/social/routes.py +++ b/federation/bp/social/routes.py @@ -212,7 +212,6 @@ def register(url_prefix="/social"): """Re-render interaction buttons after a like/boost action.""" from shared.models.federation import APInteraction from shared.browser.app.csrf import generate_csrf_token - from shared.sx.parser import SxExpr from sqlalchemy import select svc = services.federation @@ -290,9 +289,9 @@ def register(url_prefix="/social"): count=str(boost_count)) return sx_response(sx_call("federation-interaction-buttons", - like=SxExpr(like_form), - boost=SxExpr(boost_form), - reply=SxExpr(reply_sx) if reply_sx else None)) + like=like_form, + boost=boost_form, + reply=reply_sx or None)) # -- Following / Followers pagination -------------------------------------- diff --git a/federation/sx/handlers/link-card.sx b/federation/sx/handlers/link-card.sx index bed0324..cf30791 100644 --- a/federation/sx/handlers/link-card.sx +++ b/federation/sx/handlers/link-card.sx @@ -1,4 +1,5 @@ ;; Federation link-card fragment handler +;; returns: sx ;; ;; Renders actor profile preview card(s) by username. ;; Supports single mode (?slug=x or ?username=x) and batch mode (?keys=x,y,z). diff --git a/market/sx/handlers/container-nav.sx b/market/sx/handlers/container-nav.sx index 8fdc813..03019ee 100644 --- a/market/sx/handlers/container-nav.sx +++ b/market/sx/handlers/container-nav.sx @@ -1,4 +1,5 @@ ;; Market container-nav fragment handler +;; returns: sx ;; ;; Renders marketplace link nav items for blog post pages. diff --git a/market/sx/handlers/link-card.sx b/market/sx/handlers/link-card.sx index a329555..cc517f4 100644 --- a/market/sx/handlers/link-card.sx +++ b/market/sx/handlers/link-card.sx @@ -1,4 +1,5 @@ ;; Market link-card fragment handler +;; returns: sx ;; ;; Renders product preview card(s) by slug. ;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z). diff --git a/market/sxc/pages/cards.py b/market/sxc/pages/cards.py index f5ef786..9ca6ad0 100644 --- a/market/sxc/pages/cards.py +++ b/market/sxc/pages/cards.py @@ -188,9 +188,9 @@ def _market_card_sx(market: Any, page_info: dict, *, show_page_badge: bool = Tru return sx_call( "market-market-card", - title_content=SxExpr(title_sx) if title_sx else None, - desc_content=SxExpr(desc_sx) if desc_sx else None, - badge_content=SxExpr(badge_sx) if badge_sx else None, + title_content=title_sx or None, + desc_content=desc_sx or None, + badge_content=badge_sx or None, ) diff --git a/market/sxc/pages/filters.py b/market/sxc/pages/filters.py index 6b01864..8637fc2 100644 --- a/market/sxc/pages/filters.py +++ b/market/sxc/pages/filters.py @@ -126,7 +126,7 @@ async def _desktop_filter_sx(ctx: dict) -> str: if brands: brand_inner = _brand_filter_sx(brands, selected_brands, ctx) brand_summary = sx_call("market-desktop-brand-summary", - inner=SxExpr(brand_inner) if brand_inner else None) + inner=brand_inner or None) return "(<> " + " ".join([search_sx, cat_summary, brand_summary]) + ")" @@ -226,8 +226,8 @@ async def _mobile_filter_summary_sx(ctx: dict) -> str: return sx_call( "market-mobile-filter-summary", - search_bar=SxExpr(search_bar), - chips=SxExpr(chips_row), + search_bar=search_bar, + chips=chips_row, filter=SxExpr(mobile_filter), ) diff --git a/market/sxc/pages/helpers.py b/market/sxc/pages/helpers.py index 8bbd7b7..ab41497 100644 --- a/market/sxc/pages/helpers.py +++ b/market/sxc/pages/helpers.py @@ -151,10 +151,9 @@ async def _h_page_markets_content(slug=None, **kw): async def _h_page_admin_content(slug=None, **kw): from shared.sx.page import get_template_context from shared.sx.helpers import sx_call - from shared.sx.parser import SxExpr ctx = await get_template_context() content = await _markets_admin_panel_sx(ctx) - return sx_call("market-admin-content-wrap", inner=SxExpr(content)) + return sx_call("market-admin-content-wrap", inner=content) def _h_market_home_content(page_slug=None, market_slug=None, **kw): diff --git a/market/sxc/pages/layouts.py b/market/sxc/pages/layouts.py index e0d4c76..ca29a59 100644 --- a/market/sxc/pages/layouts.py +++ b/market/sxc/pages/layouts.py @@ -44,8 +44,8 @@ def _market_header_sx(ctx: dict, *, oob: bool = False) -> str: return sx_call( "menu-row-sx", id="market-row", level=2, - link_href=link_href, link_label_content=SxExpr(label_sx), - nav=SxExpr(nav_sx) if nav_sx else None, + link_href=link_href, link_label_content=label_sx, + nav=nav_sx or None, child_id="market-header-child", oob=oob, ) @@ -87,7 +87,7 @@ def _desktop_category_nav_sx(ctx: dict, categories: dict, qs: str, return sx_call("market-desktop-category-nav", links=SxExpr(links_sx), - admin=SxExpr(admin_sx) if admin_sx else None) + admin=admin_sx or None) def _product_header_sx(ctx: dict, d: dict, *, oob: bool = False) -> str: @@ -117,7 +117,7 @@ def _product_header_sx(ctx: dict, d: dict, *, oob: bool = False) -> str: return sx_call( "menu-row-sx", id="product-row", level=3, - link_href=link_href, link_label_content=SxExpr(label_sx), + link_href=link_href, link_label_content=label_sx, nav=SxExpr(nav_sx), child_id="product-header-child", oob=oob, ) @@ -219,7 +219,7 @@ def _mobile_nav_panel_sx(ctx: dict) -> str: bg_cls=bg_cls, href=cat_href, hx_select=hx_select, select_colours=select_colours, cat_name=cat, count_label=f"{cat_count} products", count_str=str(cat_count), - chevron=SxExpr(chevron_sx), + chevron=chevron_sx, ) subs = data.get("subs", []) @@ -246,8 +246,8 @@ def _mobile_nav_panel_sx(ctx: dict) -> str: item_parts.append(sx_call( "market-mobile-cat-details", open=cat_active or None, - summary=SxExpr(summary_sx), - subs=SxExpr(subs_sx), + summary=summary_sx, + subs=subs_sx, )) items_sx = "(<> " + " ".join(item_parts) + ")" @@ -295,16 +295,16 @@ def _register_market_layouts() -> None: 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))) + post_header=await _post_header_sx(ctx), + market_header=_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)), + 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"))) @@ -317,17 +317,17 @@ 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))) + post_header=await _post_header_sx(ctx), + market_header=_market_header_sx(ctx), + admin_header=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))), + market_header_oob=_market_header_sx(ctx, oob=True), + admin_oob_header=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"))) diff --git a/market/sxc/pages/renders.py b/market/sxc/pages/renders.py index 4df1272..ce6d8c6 100644 --- a/market/sxc/pages/renders.py +++ b/market/sxc/pages/renders.py @@ -37,8 +37,8 @@ async def render_browse_page(ctx: dict) -> str: from shared.sx.helpers import render_to_sx_with_env hdr = 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))) + post_header=await _post_header_sx(ctx), + market_header=_market_header_sx(ctx)) menu = _mobile_nav_panel_sx(ctx) filter_sx = await _mobile_filter_summary_sx(ctx) aside_sx = await _desktop_filter_sx(ctx) @@ -55,8 +55,8 @@ async def render_browse_oob(ctx: dict) -> str: 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=SxExpr(oob_hdr), - post_header_oob=SxExpr(await _post_header_sx(ctx, oob=True)), + 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"))) menu = _mobile_nav_panel_sx(ctx) @@ -83,9 +83,9 @@ async def render_product_page(ctx: dict, d: dict) -> str: from shared.sx.helpers import render_to_sx_with_env hdr = await render_to_sx_with_env("market-product-layout-full", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - market_header=SxExpr(_market_header_sx(ctx)), - product_header=SxExpr(_product_header_sx(ctx, d))) + post_header=await _post_header_sx(ctx), + market_header=_market_header_sx(ctx), + product_header=_product_header_sx(ctx, d)) return await full_page_sx(ctx, header_rows=hdr, content=content, meta=meta) @@ -114,10 +114,10 @@ async def render_product_admin_page(ctx: dict, d: dict) -> str: from shared.sx.helpers import render_to_sx_with_env hdr = await render_to_sx_with_env("market-product-admin-layout-full", {}, - post_header=SxExpr(await _post_header_sx(ctx)), - market_header=SxExpr(_market_header_sx(ctx)), - product_header=SxExpr(_product_header_sx(ctx, d)), - admin_header=SxExpr(_product_admin_header_sx(ctx, d))) + post_header=await _post_header_sx(ctx), + market_header=_market_header_sx(ctx), + product_header=_product_header_sx(ctx, d), + admin_header=_product_admin_header_sx(ctx, d)) return await full_page_sx(ctx, header_rows=hdr, content=content) @@ -243,7 +243,7 @@ def render_cart_added_response(cart: list, item: Any, d: dict) -> str: add_sx = sx_call( "market-cart-add-oob", id=f"cart-add-{slug}", - inner=SxExpr(cart_add), + inner=cart_add, ) return "(<> " + cart_mini + " " + add_sx + ")" diff --git a/market/sxc/pages/utils.py b/market/sxc/pages/utils.py index ee0ab48..67446af 100644 --- a/market/sxc/pages/utils.py +++ b/market/sxc/pages/utils.py @@ -110,7 +110,7 @@ def _product_detail_sx(d: dict, ctx: dict) -> str: gallery_inner = sx_call( "market-detail-gallery-inner", - like=SxExpr(like_sx) if like_sx else None, + like=like_sx or None, image=images[0], alt=d.get("title", ""), labels=SxExpr(labels_sx) if labels_sx else None, brand=brand, @@ -123,8 +123,8 @@ def _product_detail_sx(d: dict, ctx: dict) -> str: gallery_sx = sx_call( "market-detail-gallery", - inner=SxExpr(gallery_inner), - nav=SxExpr(nav_buttons) if nav_buttons else None, + inner=gallery_inner, + nav=nav_buttons or None, ) # Thumbnails @@ -144,7 +144,7 @@ def _product_detail_sx(d: dict, ctx: dict) -> str: if user: like_sx = _like_button_sx(slug, liked_by_current_user, csrf, ctx) gallery_final = sx_call("market-detail-no-image", - like=SxExpr(like_sx) if like_sx else None) + like=like_sx or None) # Stickers below gallery stickers_sx = "" @@ -206,8 +206,8 @@ def _product_detail_sx(d: dict, ctx: dict) -> str: return sx_call( "market-detail-layout", gallery=SxExpr(gallery_final), - stickers=SxExpr(stickers_sx) if stickers_sx else None, - details=SxExpr(details_sx), + stickers=stickers_sx or None, + details=details_sx, ) diff --git a/orders/bp/checkout/routes.py b/orders/bp/checkout/routes.py index bc88aa8..9761b3b 100644 --- a/orders/bp/checkout/routes.py +++ b/orders/bp/checkout/routes.py @@ -45,7 +45,7 @@ async def _render_checkout_return(ctx: dict, order=None, status: str = "", else: img = sx_call("order-item-no-image") item_parts.append(sx_call("order-item-row", - href=product_url, img=SxExpr(img), + href=product_url, img=img, title=item.product_title or "Unknown product", pid=f"Product ID: {item.product_id}", qty=f"Qty: {item.quantity}", @@ -109,11 +109,11 @@ async def _render_checkout_return(ctx: dict, order=None, status: str = "", status_msg = sx_call("checkout-return-paid") content = sx_call("checkout-return-content", - summary=SxExpr(summary), - items=SxExpr(items) if items else None, - calendar=SxExpr(calendar) if calendar else None, - tickets=SxExpr(tickets) if tickets else None, - status_message=SxExpr(status_msg) if status_msg else None, + summary=summary, + items=items or None, + calendar=calendar or None, + tickets=tickets or None, + status_message=status_msg or None, ) account_url = call_url(ctx, "account_url", "") diff --git a/orders/bp/order/routes.py b/orders/bp/order/routes.py index 03c502f..fe3a84e 100644 --- a/orders/bp/order/routes.py +++ b/orders/bp/order/routes.py @@ -71,7 +71,6 @@ def register() -> Blueprint: if not hosted_url: from shared.sx.page import get_template_context from shared.sx.helpers import sx_call, root_header_sx, header_child_sx, full_page_sx, call_url - from shared.sx.parser import SxExpr from shared.infrastructure.urls import cart_url tctx = await get_template_context() account_url = call_url(tctx, "account_url", "") @@ -82,7 +81,7 @@ def register() -> Blueprint: content = sx_call( "checkout-error-content", msg="No hosted checkout URL returned from SumUp when trying to reopen payment.", - order=SxExpr(order_sx), + order=order_sx, back_url=cart_url("/"), ) html = await full_page_sx(tctx, header_rows=hdr, filter=filt, content=content) diff --git a/orders/sx/handlers/account-nav-item.sx b/orders/sx/handlers/account-nav-item.sx index f679d81..9d4f007 100644 --- a/orders/sx/handlers/account-nav-item.sx +++ b/orders/sx/handlers/account-nav-item.sx @@ -1,4 +1,5 @@ ;; Orders account-nav-item fragment handler +;; returns: sx ;; ;; Renders the "orders" link for the account dashboard nav. diff --git a/relations/sx/handlers/container-nav.sx b/relations/sx/handlers/container-nav.sx index c9cd863..fb580db 100644 --- a/relations/sx/handlers/container-nav.sx +++ b/relations/sx/handlers/container-nav.sx @@ -1,4 +1,5 @@ ;; Relations container-nav fragment handler +;; returns: sx ;; ;; Generic navigation fragment driven by the relation registry. ;; Renders nav items for all related entities of a container. diff --git a/shared/sx/async_eval.py b/shared/sx/async_eval.py index 49f4d1f..7eed7b3 100644 --- a/shared/sx/async_eval.py +++ b/shared/sx/async_eval.py @@ -1010,10 +1010,10 @@ async def async_eval_to_sx( ctx = RequestContext() result = await _aser(expr, env, ctx) if isinstance(result, SxExpr): - return result.source + return result if result is None or result is NIL: - return "" - return serialize(result) + return SxExpr("") + return SxExpr(serialize(result)) async def async_eval_slot_to_sx( @@ -1039,10 +1039,10 @@ async def async_eval_slot_to_sx( if isinstance(comp, Component): result = await _aser_component(comp, expr[1:], env, ctx) if isinstance(result, SxExpr): - return result.source + return result if result is None or result is NIL: - return "" - return serialize(result) + return SxExpr("") + return SxExpr(serialize(result)) else: import logging logging.getLogger("sx.eval").error( @@ -1056,14 +1056,10 @@ async def async_eval_slot_to_sx( # Fall back to normal async_eval_to_sx result = await _aser(expr, env, ctx) if isinstance(result, SxExpr): - return result.source - if result is None or result is NIL: - return "" - # Page helpers return SX source strings from render_to_sx() — - # pass through directly instead of quoting via serialize(). - if isinstance(result, str): return result - return serialize(result) + if result is None or result is NIL: + return SxExpr("") + return SxExpr(serialize(result)) async def _aser(expr: Any, env: dict[str, Any], ctx: RequestContext) -> Any: @@ -1071,10 +1067,10 @@ async def _aser(expr: Any, env: dict[str, Any], ctx: RequestContext) -> Any: for everything else.""" if isinstance(expr, (int, float, bool)): return expr - if isinstance(expr, str): - return expr if isinstance(expr, SxExpr): return expr + if isinstance(expr, str): + return expr if expr is None or expr is NIL: return NIL diff --git a/shared/sx/handlers.py b/shared/sx/handlers.py index c18f551..40b3b57 100644 --- a/shared/sx/handlers.py +++ b/shared/sx/handlers.py @@ -111,16 +111,19 @@ async def execute_handler( service_name: str, args: dict[str, str] | None = None, ) -> str: - """Execute a declarative handler and return rendered sx/HTML string. + """Execute a declarative handler and return SX wire format (``SxExpr``). - Uses the async evaluator+renderer so I/O primitives (``query``, - ``service``, ``request-arg``, etc.) are awaited inline within - control flow — no collect-then-substitute limitations. + Uses the async evaluator so I/O primitives (``query``, ``service``, + ``request-arg``, etc.) are awaited inline within control flow. + + Returns ``SxExpr`` — pre-built sx source. Callers like + ``fetch_fragment`` check ``content-type: text/sx`` and wrap the + response in ``SxExpr`` when consuming cross-service fragments. 1. Build env from component env + handler closure 2. Bind handler params from args (typically request.args) - 3. Evaluate + render via async_render (handles I/O inline) - 4. Return rendered string + 3. Evaluate via ``async_eval_to_sx`` (I/O inline, components serialized) + 4. Return ``SxExpr`` wire format """ from .jinja_bridge import get_component_env, _get_request_context from .async_eval import async_eval_to_sx diff --git a/shared/sx/helpers.py b/shared/sx/helpers.py index cfe5a5d..6d7fba0 100644 --- a/shared/sx/helpers.py +++ b/shared/sx/helpers.py @@ -74,10 +74,10 @@ async def root_header_sx(ctx: dict, *, oob: bool = False) -> str: ) -def mobile_menu_sx(*sections: str) -> str: +def mobile_menu_sx(*sections: str) -> SxExpr: """Assemble mobile menu from pre-built sections (deepest first).""" parts = [s for s in sections if s] - return "(<> " + " ".join(parts) + ")" if parts else "" + return SxExpr("(<> " + " ".join(parts) + ")") if parts else SxExpr("") async def mobile_root_nav_sx(ctx: dict) -> str: @@ -96,13 +96,13 @@ async def mobile_root_nav_sx(ctx: dict) -> str: # Shared nav-item builders — used by BOTH desktop headers and mobile menus # --------------------------------------------------------------------------- -async def _post_nav_items_sx(ctx: dict) -> str: +async def _post_nav_items_sx(ctx: dict) -> SxExpr: """Build post-level nav items (container_nav + admin cog). Shared by ``post_header_sx`` (desktop) and ``post_mobile_nav_sx`` (mobile).""" post = ctx.get("post") or {} slug = post.get("slug", "") if not slug: - return "" + return SxExpr("") parts: list[str] = [] page_cart_count = ctx.get("page_cart_count", 0) if page_cart_count and page_cart_count > 0: @@ -130,11 +130,11 @@ async def _post_nav_items_sx(ctx: dict) -> str: is_admin_page=is_admin_page or None) if admin_nav: parts.append(admin_nav) - return "(<> " + " ".join(parts) + ")" if parts else "" + return SxExpr("(<> " + " ".join(parts) + ")") if parts else SxExpr("") async def _post_admin_nav_items_sx(ctx: dict, slug: str, - selected: str = "") -> str: + selected: str = "") -> SxExpr: """Build post-admin nav items (calendars, markets, etc.). Shared by ``post_admin_header_sx`` (desktop) and mobile menu.""" select_colours = ctx.get("select_colours", "") @@ -158,7 +158,7 @@ async def _post_admin_nav_items_sx(ctx: dict, slug: str, parts.append(await _render_to_sx("nav-link", href=href, label=label, select_colours=select_colours, is_selected=is_sel or None)) - return "(<> " + " ".join(parts) + ")" if parts else "" + return SxExpr("(<> " + " ".join(parts) + ")") if parts else SxExpr("") # --------------------------------------------------------------------------- @@ -177,7 +177,7 @@ async def post_mobile_nav_sx(ctx: dict) -> str: label=title, href=call_url(ctx, "blog_url", f"/{slug}/"), level=1, - items=SxExpr(nav), + items=nav, ) @@ -220,8 +220,8 @@ async def post_header_sx(ctx: dict, *, oob: bool = False, child: str = "") -> st return await _render_to_sx("menu-row-sx", id="post-row", level=1, link_href=link_href, - link_label_content=SxExpr(label_sx), - nav=SxExpr(nav_sx) if nav_sx else None, + link_label_content=label_sx, + nav=nav_sx, child_id="post-header-child", child=SxExpr(child) if child else None, oob=oob, external=True, @@ -244,8 +244,8 @@ async def post_admin_header_sx(ctx: dict, slug: str, *, oob: bool = False, return await _render_to_sx("menu-row-sx", id="post-admin-row", level=2, link_href=admin_href, - link_label_content=SxExpr(label_sx), - nav=SxExpr(nav_sx) if nav_sx else None, + link_label_content=label_sx, + nav=nav_sx, child_id="post-admin-header-child", oob=oob, ) @@ -352,7 +352,7 @@ async def _render_to_sx_with_env(__name: str, extra_env: dict, **kwargs: Any) -> env = dict(get_component_env()) env.update(extra_env) ctx = _get_request_context() - return await async_eval_slot_to_sx(ast, env, ctx) + return SxExpr(await async_eval_slot_to_sx(ast, env, ctx)) async def _render_to_sx(__name: str, **kwargs: Any) -> str: @@ -371,7 +371,7 @@ async def _render_to_sx(__name: str, **kwargs: Any) -> str: ast = _build_component_ast(__name, **kwargs) env = dict(get_component_env()) ctx = _get_request_context() - return await async_eval_to_sx(ast, env, ctx) + return SxExpr(await async_eval_to_sx(ast, env, ctx)) # Backwards-compat alias — layout infrastructure still imports this. @@ -420,7 +420,7 @@ def sx_call(component_name: str, **kwargs: Any) -> str: parts.append("(list " + " ".join(items) + ")") else: parts.append(serialize(val)) - return "(" + " ".join(parts) + ")" + return SxExpr("(" + " ".join(parts) + ")") diff --git a/shared/sx/parser.py b/shared/sx/parser.py index 15c9a7c..1abe667 100644 --- a/shared/sx/parser.py +++ b/shared/sx/parser.py @@ -25,31 +25,37 @@ from .types import Keyword, Symbol, NIL # SxExpr — pre-built sx source marker # --------------------------------------------------------------------------- -class SxExpr: +class SxExpr(str): """Pre-built sx source that serialize() outputs unquoted. + ``SxExpr`` is a ``str`` subclass, so it works everywhere a plain + string does (join, startswith, f-strings, isinstance checks). The + only difference: ``serialize()`` emits it unquoted instead of + wrapping it in double-quotes. + Use this to nest sx call strings inside other sx_call() invocations without them being quoted as strings:: - sx_call("parent", child=SxExpr(sx_call("child", x=1))) + sx_call("parent", child=sx_call("child", x=1)) # => (~parent :child (~child :x 1)) """ - __slots__ = ("source",) - def __init__(self, source: str): - self.source = source + def __new__(cls, source: str = "") -> "SxExpr": + return str.__new__(cls, source) + + @property + def source(self) -> str: + """The raw SX source string (backward compat).""" + return str.__str__(self) def __repr__(self) -> str: - return f"SxExpr({self.source!r})" - - def __str__(self) -> str: - return self.source + return f"SxExpr({str.__repr__(self)})" def __add__(self, other: object) -> "SxExpr": - return SxExpr(self.source + str(other)) + return SxExpr(str.__add__(self, str(other))) def __radd__(self, other: object) -> "SxExpr": - return SxExpr(str(other) + self.source) + return SxExpr(str.__add__(str(other), self)) # --------------------------------------------------------------------------- @@ -283,7 +289,26 @@ def _parse_map(tok: Tokenizer) -> dict[str, Any]: # --------------------------------------------------------------------------- def serialize(expr: Any, indent: int = 0, pretty: bool = False) -> str: - """Serialize a value back to s-expression text.""" + """Serialize a value back to s-expression text. + + Type dispatch order (first match wins): + + - ``SxExpr`` → emitted unquoted (pre-built sx source) + - ``list`` → ``(head ...)`` (s-expression list) + - ``Symbol`` → bare name + - ``Keyword`` → ``:name`` + - ``str`` → ``"quoted"`` (with escapes) + - ``bool`` → ``true`` / ``false`` + - ``int/float`` → numeric literal + - ``None/NIL`` → ``nil`` + - ``dict`` → ``{:key val ...}`` + + List serialization conventions (for ``sx_call`` kwargs): + + - ``(list ...)`` — data array: client gets iterable for map/filter + - ``(<> ...)`` — rendered content: client treats as DocumentFragment + - ``(head ...)`` — AST: head is called as function (never use for data) + """ if isinstance(expr, SxExpr): return expr.source diff --git a/sx/sxc/pages/layouts.py b/sx/sxc/pages/layouts.py index ebd22db..7e282d2 100644 --- a/sx/sxc/pages/layouts.py +++ b/sx/sxc/pages/layouts.py @@ -16,30 +16,27 @@ def _register_sx_layouts() -> None: async def _sx_full_headers(ctx: dict, **kw: Any) -> str: """Full headers for sx home page: root + sx menu row.""" from shared.sx.helpers import render_to_sx_with_env - from shared.sx.parser import SxExpr main_nav = _main_nav_sx(kw.get("section")) sx_row = _sx_header_sx(main_nav) return await render_to_sx_with_env("sx-layout-full", {}, - sx_row=SxExpr(sx_row)) + sx_row=sx_row) async def _sx_oob_headers(ctx: dict, **kw: Any) -> str: """OOB headers for sx home page.""" from shared.sx.helpers import render_to_sx_with_env, oob_header_sx - from shared.sx.parser import SxExpr main_nav = _main_nav_sx(kw.get("section")) sx_row = _sx_header_sx(main_nav) rows = await render_to_sx_with_env("sx-layout-full", {}, - sx_row=SxExpr(sx_row)) + sx_row=sx_row) return await oob_header_sx("root-header-child", "sx-header-child", rows) async def _sx_section_full_headers(ctx: dict, **kw: Any) -> str: """Full headers for sx section pages: root + sx row + sub row.""" from shared.sx.helpers import render_to_sx_with_env - from shared.sx.parser import SxExpr section = kw.get("section", "") sub_label = kw.get("sub_label", section) @@ -51,13 +48,12 @@ async def _sx_section_full_headers(ctx: dict, **kw: Any) -> str: sub_row = _sub_row_sx(sub_label, sub_href, sub_nav, selected) sx_row = _sx_header_sx(main_nav, child=sub_row) return await render_to_sx_with_env("sx-section-layout-full", {}, - sx_row=SxExpr(sx_row)) + sx_row=sx_row) async def _sx_section_oob_headers(ctx: dict, **kw: Any) -> str: """OOB headers for sx section pages.""" from shared.sx.helpers import render_to_sx_with_env, oob_header_sx - from shared.sx.parser import SxExpr section = kw.get("section", "") sub_label = kw.get("sub_label", section) @@ -69,7 +65,7 @@ async def _sx_section_oob_headers(ctx: dict, **kw: Any) -> str: sub_row = _sub_row_sx(sub_label, sub_href, sub_nav, selected) sx_row = _sx_header_sx(main_nav, child=sub_row) rows = await render_to_sx_with_env("sx-section-layout-full", {}, - sx_row=SxExpr(sx_row)) + sx_row=sx_row) return await oob_header_sx("root-header-child", "sx-header-child", rows) diff --git a/sx/sxc/pages/utils.py b/sx/sxc/pages/utils.py index fe49b66..f08e5de 100644 --- a/sx/sxc/pages/utils.py +++ b/sx/sxc/pages/utils.py @@ -68,7 +68,7 @@ def _sx_header_sx(nav: str | None = None, *, child: str | None = None) -> str: return sx_call("menu-row-sx", id="sx-row", level=1, colour="violet", link_href="/", link_label="sx", - link_label_content=SxExpr(label_sx), + link_label_content=label_sx, nav=SxExpr(nav) if nav else None, child_id="sx-header-child", child=SxExpr(child) if child else None, diff --git a/test/sxc/pages/renders.py b/test/sxc/pages/renders.py index fad2246..fe198ad 100644 --- a/test/sxc/pages/renders.py +++ b/test/sxc/pages/renders.py @@ -5,7 +5,7 @@ import os from datetime import datetime from shared.sx.jinja_bridge import load_service_components -from shared.sx.helpers import sx_call, SxExpr, render_to_sx_with_env, full_page_sx +from shared.sx.helpers import sx_call, render_to_sx_with_env, full_page_sx # Load test-specific .sx components at import time load_service_components(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) @@ -98,7 +98,7 @@ async def render_dashboard_page_sx(ctx: dict, result: dict | None, inner = sx_call("test-results-partial", summary_data=summary_data, sections=sections, has_failures=has_failures) - content = sx_call("test-results-wrap", running=running, inner=SxExpr(inner)) + content = sx_call("test-results-wrap", running=running, inner=inner) hdr = await render_to_sx_with_env("test-layout-full", {}, services=_service_list(), active_service=active_service, @@ -126,7 +126,7 @@ async def render_results_partial_sx(result: dict | None, running: bool, inner = sx_call("test-results-partial", summary_data=summary_data, sections=sections, has_failures=has_failures) - return sx_call("test-results-wrap", running=running, inner=SxExpr(inner)) + return sx_call("test-results-wrap", running=running, inner=inner) async def render_test_detail_page_sx(ctx: dict, test: dict) -> str: