Make SxExpr a str subclass, sx_call/render functions return SxExpr
SxExpr is now a str subclass so it works everywhere a plain string does (join, isinstance, f-strings) while serialize() still emits it unquoted. sx_call() and all internal render functions (_render_to_sx, async_eval_to_sx, etc.) return SxExpr, eliminating the "forgot to wrap" bug class that caused the sx_content leak and list serialization bugs. - Phase 0: SxExpr(str) with .source property, __add__/__radd__ - Phase 1: sx_call returns SxExpr (drop-in, all 200+ sites unchanged) - Phase 2: async_eval_to_sx, async_eval_slot_to_sx, _render_to_sx, mobile_menu_sx return SxExpr; remove isinstance(str) workaround - Phase 3: Remove ~150 redundant SxExpr() wrappings across 45 files - Phase 4: serialize() docstring, handler return docs, ;; returns: sx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
;; Account auth-menu fragment handler
|
;; Account auth-menu fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders the desktop + mobile auth menu (sign-in or user link).
|
;; Renders the desktop + mobile auth menu (sign-in or user link).
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ def _render_page_search_results(pages, query, page, has_more) -> str:
|
|||||||
items_sx = "(<> " + " ".join(items) + ")"
|
items_sx = "(<> " + " ".join(items) + ")"
|
||||||
return sx_call("page-search-results",
|
return sx_call("page-search-results",
|
||||||
items=SxExpr(items_sx),
|
items=SxExpr(items_sx),
|
||||||
sentinel=SxExpr(sentinel) if sentinel else None)
|
sentinel=sentinel or None)
|
||||||
|
|
||||||
|
|
||||||
def _render_menu_items_nav_oob(menu_items) -> str:
|
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":
|
if item_slug != "cart":
|
||||||
item_parts.append(sx_call("blog-nav-item-link",
|
item_parts.append(sx_call("blog-nav-item-link",
|
||||||
href=href, hx_get=f"/{item_slug}/", selected=selected,
|
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:
|
else:
|
||||||
item_parts.append(sx_call("blog-nav-item-plain",
|
item_parts.append(sx_call("blog-nav-item-plain",
|
||||||
href=href, selected=selected, nav_cls=nav_button_cls,
|
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 ""
|
items_sx = "(<> " + " ".join(item_parts) + ")" if item_parts else ""
|
||||||
|
|||||||
@@ -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",
|
confirm_text=f"This will remove {e_name} from this post",
|
||||||
toggle_url=toggle_url,
|
toggle_url=toggle_url,
|
||||||
hx_headers=f'{{"X-CSRFToken": "{csrf}"}}',
|
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}",
|
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:
|
else:
|
||||||
content_sx = sx_call("blog-associated-entries-empty")
|
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:
|
def _render_nav_entries_oob(associated_entries, calendars, post: dict) -> str:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Blog link-card fragment handler
|
;; Blog link-card fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders link-card(s) for blog posts by slug.
|
;; Renders link-card(s) for blog posts by slug.
|
||||||
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Blog nav-tree fragment handler
|
;; Blog nav-tree fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders the full scrollable navigation menu bar with app icons.
|
;; Renders the full scrollable navigation menu bar with app icons.
|
||||||
;; Uses nav-tree I/O primitive to fetch menu nodes from the blog DB.
|
;; Uses nav-tree I/O primitive to fetch menu nodes from the blog DB.
|
||||||
|
|||||||
@@ -279,11 +279,11 @@ async def _h_post_preview_content(slug=None, **kw):
|
|||||||
if preview.get("sx_rendered"):
|
if preview.get("sx_rendered"):
|
||||||
rendered_sx = sx_call("blog-preview-rendered", html=preview["sx_rendered"])
|
rendered_sx = sx_call("blog-preview-rendered", html=preview["sx_rendered"])
|
||||||
sections.append(sx_call("blog-preview-section",
|
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"):
|
if preview.get("lex_rendered"):
|
||||||
rendered_sx = sx_call("blog-preview-rendered", html=preview["lex_rendered"])
|
rendered_sx = sx_call("blog-preview-rendered", html=preview["lex_rendered"])
|
||||||
sections.append(sx_call("blog-preview-section",
|
sections.append(sx_call("blog-preview-section",
|
||||||
title="Lexical Rendered", content=SxExpr(rendered_sx)))
|
title="Lexical Rendered", content=rendered_sx))
|
||||||
|
|
||||||
if not sections:
|
if not sections:
|
||||||
return sx_call("blog-preview-empty")
|
return sx_call("blog-preview-empty")
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from typing import Any
|
|||||||
|
|
||||||
def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
||||||
from shared.sx.helpers import sx_call
|
from shared.sx.helpers import sx_call
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
from quart import url_for as qurl
|
from quart import url_for as qurl
|
||||||
|
|
||||||
settings_href = qurl("settings.defpage_settings_home")
|
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",
|
return sx_call("menu-row-sx",
|
||||||
id="root-settings-row", level=1,
|
id="root-settings-row", level=1,
|
||||||
link_href=settings_href,
|
link_href=settings_href,
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
nav=nav_sx or None,
|
||||||
child_id="root-settings-header-child", oob=oob)
|
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",
|
return sx_call("menu-row-sx",
|
||||||
id=row_id, level=2,
|
id=row_id, level=2,
|
||||||
link_href=href,
|
link_href=href,
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
nav=SxExpr(nav_sx) if nav_sx else None,
|
||||||
child_id=child_id, oob=oob)
|
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:
|
async def _settings_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
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:
|
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.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", {},
|
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)
|
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,
|
async def _sub_settings_full(ctx: dict, row_id: str, child_id: str,
|
||||||
endpoint: str, icon: str, label: str) -> str:
|
endpoint: str, icon: str, label: str) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_env
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
from quart import url_for as qurl
|
from quart import url_for as qurl
|
||||||
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
||||||
settings_header=SxExpr(_settings_header_sx(ctx)),
|
settings_header=_settings_header_sx(ctx),
|
||||||
sub_header=SxExpr(_sub_settings_header_sx(
|
sub_header=_sub_settings_header_sx(
|
||||||
row_id, child_id, qurl(endpoint), icon, label, ctx)))
|
row_id, child_id, qurl(endpoint), icon, label, ctx))
|
||||||
|
|
||||||
|
|
||||||
async def _sub_settings_oob(ctx: dict, row_id: str, child_id: str,
|
async def _sub_settings_oob(ctx: dict, row_id: str, child_id: str,
|
||||||
endpoint: str, icon: str, label: str) -> str:
|
endpoint: str, icon: str, label: str) -> str:
|
||||||
from shared.sx.helpers import oob_header_sx, sx_call
|
from shared.sx.helpers import oob_header_sx, sx_call
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
from quart import url_for as qurl
|
from quart import url_for as qurl
|
||||||
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
||||||
sub_hdr = _sub_settings_header_sx(
|
sub_hdr = _sub_settings_header_sx(
|
||||||
row_id, child_id, qurl(endpoint), icon, label, ctx)
|
row_id, child_id, qurl(endpoint), icon, label, ctx)
|
||||||
sub_oob = await oob_header_sx("root-settings-header-child", child_id, sub_hdr)
|
sub_oob = await oob_header_sx("root-settings-header-child", child_id, sub_hdr)
|
||||||
return sx_call("sub-settings-layout-oob",
|
return sx_call("sub-settings-layout-oob",
|
||||||
settings_header_oob=SxExpr(settings_hdr_oob),
|
settings_header_oob=settings_hdr_oob,
|
||||||
sub_header_oob=SxExpr(sub_oob))
|
sub_header_oob=sub_oob)
|
||||||
|
|
||||||
|
|
||||||
# --- Cache ---
|
# --- 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:
|
async def _tag_group_edit_full(ctx: dict, **kw: Any) -> str:
|
||||||
from quart import request, url_for as qurl
|
from quart import request, url_for as qurl
|
||||||
from shared.sx.helpers import render_to_sx_with_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")
|
g_id = (request.view_args or {}).get("id")
|
||||||
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
||||||
settings_header=SxExpr(_settings_header_sx(ctx)),
|
settings_header=_settings_header_sx(ctx),
|
||||||
sub_header=SxExpr(_sub_settings_header_sx(
|
sub_header=_sub_settings_header_sx(
|
||||||
"tag-groups-row", "tag-groups-header-child",
|
"tag-groups-row", "tag-groups-header-child",
|
||||||
qurl("defpage_tag_group_edit", id=g_id),
|
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:
|
async def _tag_group_edit_oob(ctx: dict, **kw: Any) -> str:
|
||||||
from quart import request, url_for as qurl
|
from quart import request, url_for as qurl
|
||||||
from shared.sx.helpers import oob_header_sx, sx_call
|
from shared.sx.helpers import oob_header_sx, sx_call
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
g_id = (request.view_args or {}).get("id")
|
g_id = (request.view_args or {}).get("id")
|
||||||
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
||||||
sub_hdr = _sub_settings_header_sx(
|
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)
|
"tags", "Tag Groups", ctx)
|
||||||
sub_oob = await oob_header_sx("root-settings-header-child", "tag-groups-header-child", sub_hdr)
|
sub_oob = await oob_header_sx("root-settings-header-child", "tag-groups-header-child", sub_hdr)
|
||||||
return sx_call("sub-settings-layout-oob",
|
return sx_call("sub-settings-layout-oob",
|
||||||
settings_header_oob=SxExpr(settings_hdr_oob),
|
settings_header_oob=settings_hdr_oob,
|
||||||
sub_header_oob=SxExpr(sub_oob))
|
sub_header_oob=sub_oob)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Cart account-nav-item fragment handler
|
;; Cart account-nav-item fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders the "orders" link for the account dashboard nav.
|
;; Renders the "orders" link for the account dashboard nav.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Cart cart-mini fragment handler
|
;; Cart cart-mini fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders the cart icon with badge (or logo when empty).
|
;; Renders the cart icon with badge (or logo when empty).
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
|
|
||||||
|
|
||||||
def _register_cart_layouts() -> None:
|
def _register_cart_layouts() -> None:
|
||||||
from shared.sx.layouts import register_custom_layout
|
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",
|
"menu-row-sx",
|
||||||
id="page-cart-row", level=2, colour="sky",
|
id="page-cart-row", level=2, colour="sky",
|
||||||
link_href=call_url(ctx, "cart_url", f"/{slug}/"),
|
link_href=call_url(ctx, "cart_url", f"/{slug}/"),
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx), oob=oob,
|
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")
|
page_post = ctx.get("page_post")
|
||||||
env = {}
|
env = {}
|
||||||
return await render_to_sx_with_env("cart-page-layout-full", env,
|
return await render_to_sx_with_env("cart-page-layout-full", env,
|
||||||
cart_row=SxExpr(_cart_header_sx(ctx)),
|
cart_row=_cart_header_sx(ctx),
|
||||||
page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)),
|
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")
|
page_post = ctx.get("page_post")
|
||||||
env = {}
|
env = {}
|
||||||
return await render_to_sx_with_env("cart-page-layout-oob", env,
|
return await render_to_sx_with_env("cart-page-layout-oob", env,
|
||||||
root_header_oob=SxExpr(await root_header_sx(ctx, oob=True)),
|
root_header_oob=await root_header_sx(ctx, oob=True),
|
||||||
cart_row_oob=SxExpr(_cart_header_sx(ctx, oob=True)),
|
cart_row_oob=_cart_header_sx(ctx, oob=True),
|
||||||
page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)),
|
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", "")
|
selected = kw.get("selected", "")
|
||||||
env = {}
|
env = {}
|
||||||
return await render_to_sx_with_env("cart-admin-layout-full", env,
|
return await render_to_sx_with_env("cart-admin-layout-full", env,
|
||||||
post_header=SxExpr(await _post_header_sx(ctx, page_post)),
|
post_header=await _post_header_sx(ctx, page_post),
|
||||||
admin_header=SxExpr(await _cart_page_admin_header_sx(ctx, page_post, selected=selected)),
|
admin_header=await _cart_page_admin_header_sx(ctx, page_post, selected=selected),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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", {},
|
header_rows = await render_to_sx_with_env("cart-orders-layout-full", {},
|
||||||
list_url=list_url,
|
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,
|
return await full_page_sx(ctx, header_rows=header_rows, filter=filt,
|
||||||
aside=await search_desktop_sx(ctx), content=content)
|
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")
|
next_scroll = sx_call("order-end-row")
|
||||||
return sx_call("cart-orders-rows",
|
return sx_call("cart-orders-rows",
|
||||||
rows=SxExpr("(<> " + " ".join(parts) + ")"),
|
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", {},
|
oobs = await render_to_sx_with_env("cart-orders-layout-oob", {},
|
||||||
list_url=list_url,
|
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)
|
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", {})
|
hdr = await render_to_sx_with_env("layout-root-full", {})
|
||||||
filt = sx_call("checkout-error-header")
|
filt = sx_call("checkout-error-header")
|
||||||
content = sx_call("checkout-error-content", msg=err_msg,
|
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)
|
return await full_page_sx(ctx, header_rows=hdr, filter=filt, content=content)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Events account-nav-item fragment handler
|
;; Events account-nav-item fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders tickets + bookings links for the account dashboard nav.
|
;; Renders tickets + bookings links for the account dashboard nav.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Account-page fragment handler
|
;; Account-page fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders tickets or bookings panel for the account dashboard.
|
;; Renders tickets or bookings panel for the account dashboard.
|
||||||
;; slug=tickets → ticket list; slug=bookings → booking list.
|
;; slug=tickets → ticket list; slug=bookings → booking list.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Container-cards fragment handler
|
;; Container-cards fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Returns HTML with <!-- card-widget:ID --> comment markers so the
|
;; Returns HTML with <!-- card-widget:ID --> comment markers so the
|
||||||
;; blog consumer can split per-post fragments. Each post section
|
;; blog consumer can split per-post fragments. Each post section
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Events container-nav fragment handler
|
;; Events container-nav fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders calendar entry nav items + calendar link nav items
|
;; Renders calendar entry nav items + calendar link nav items
|
||||||
;; for the scrollable navigation panel on blog post pages.
|
;; for the scrollable navigation panel on blog post pages.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Events link-card fragment handler
|
;; Events link-card fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders event page preview card(s) by slug.
|
;; Renders event page preview card(s) by slug.
|
||||||
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def _calendars_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
link_href = url_for("calendars.home")
|
link_href = url_for("calendars.home")
|
||||||
return sx_call("menu-row-sx", id="calendars-row", level=3,
|
return sx_call("menu-row-sx", id="calendars-row", level=3,
|
||||||
link_href=link_href,
|
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)
|
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)
|
nav_html = _calendar_nav_sx(ctx)
|
||||||
|
|
||||||
return sx_call("menu-row-sx", id="calendar-row", level=3,
|
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)
|
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)
|
nav_html = _day_nav_sx(ctx)
|
||||||
|
|
||||||
return sx_call("menu-row-sx", id="day-row", level=4,
|
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)
|
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")
|
link_href = url_for("defpage_events_markets")
|
||||||
return sx_call("menu-row-sx", id="markets-row", level=3,
|
return sx_call("menu-row-sx", id="markets-row", level=3,
|
||||||
link_href=link_href,
|
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)
|
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 = getattr(entry, "state", "pending") or "pending"
|
||||||
state_badge = _entry_state_badge_html(state)
|
state_badge = _entry_state_badge_html(state)
|
||||||
state_td = sx_call("events-day-row-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
|
||||||
cost = getattr(entry, "cost", None)
|
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")
|
actions_td = sx_call("events-day-row-actions")
|
||||||
|
|
||||||
return sx_call("events-day-row",
|
return sx_call("events-day-row",
|
||||||
tr_cls=tr_cls, name=SxExpr(name_html), slot=SxExpr(slot_html),
|
tr_cls=tr_cls, name=name_html, slot=slot_html,
|
||||||
state=SxExpr(state_td), cost=SxExpr(cost_td),
|
state=state_td, cost=cost_td,
|
||||||
tickets=SxExpr(tickets_td), actions=SxExpr(actions_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)
|
description_html = _calendar_description_display_html(calendar, desc_edit_url)
|
||||||
|
|
||||||
return sx_call("events-calendar-admin-panel",
|
return sx_call("events-calendar-admin-panel",
|
||||||
description_content=SxExpr(description_html), csrf=csrf,
|
description_content=description_html, csrf=csrf,
|
||||||
description=desc)
|
description=desc)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ def _entry_card_html(entry, page_info: dict, pending_tickets: dict,
|
|||||||
if tp is not None:
|
if tp is not None:
|
||||||
qty = pending_tickets.get(entry.id, 0)
|
qty = pending_tickets.get(entry.id, 0)
|
||||||
widget_html = sx_call("events-entry-widget-wrapper",
|
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",
|
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),
|
time_parts=SxExpr(time_parts), cost=SxExpr(cost_html),
|
||||||
widget=SxExpr(widget_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:
|
if tp is not None:
|
||||||
qty = pending_tickets.get(entry.id, 0)
|
qty = pending_tickets.get(entry.id, 0)
|
||||||
widget_html = sx_call("events-entry-tile-widget-wrapper",
|
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",
|
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),
|
time=SxExpr(time_html), cost=SxExpr(cost_html),
|
||||||
widget=SxExpr(widget_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")
|
cls="px-3 py-12 text-center text-stone-400")
|
||||||
|
|
||||||
return sx_call("events-main-panel-body",
|
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
|
||||||
state_html = _field("State", sx_call("events-entry-state-field",
|
state_html = _field("State", sx_call("events-entry-state-field",
|
||||||
entry_id=str(eid),
|
entry_id=str(eid),
|
||||||
badge=SxExpr(_entry_state_badge_html(state))))
|
badge=_entry_state_badge_html(state)))
|
||||||
|
|
||||||
# Cost
|
# Cost
|
||||||
cost = getattr(entry, "cost", None)
|
cost = getattr(entry, "cost", None)
|
||||||
@@ -284,7 +284,7 @@ def _entry_main_panel_html(ctx: dict) -> str:
|
|||||||
entry_posts = ctx.get("entry_posts") or []
|
entry_posts = ctx.get("entry_posts") or []
|
||||||
posts_html = _field("Associated Posts", sx_call("events-entry-posts-field",
|
posts_html = _field("Associated Posts", sx_call("events-entry-posts-field",
|
||||||
entry_id=str(eid),
|
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
|
# Options and Edit Button
|
||||||
edit_url = url_for(
|
edit_url = url_for(
|
||||||
@@ -295,12 +295,12 @@ def _entry_main_panel_html(ctx: dict) -> str:
|
|||||||
|
|
||||||
return sx_call("events-entry-panel",
|
return sx_call("events-entry-panel",
|
||||||
entry_id=str(eid), list_container=list_container,
|
entry_id=str(eid), list_container=list_container,
|
||||||
name=SxExpr(name_html), slot=SxExpr(slot_html),
|
name=name_html, slot=slot_html,
|
||||||
time=SxExpr(time_html), state=SxExpr(state_html),
|
time=time_html, state=state_html,
|
||||||
cost=SxExpr(cost_html), tickets=SxExpr(tickets_html),
|
cost=cost_html, tickets=tickets_html,
|
||||||
buy=SxExpr(buy_html), date=SxExpr(date_html),
|
buy=SxExpr(buy_html), date=date_html,
|
||||||
posts=SxExpr(posts_html),
|
posts=posts_html,
|
||||||
options=SxExpr(_entry_options_html(entry, calendar, day, month, year)),
|
options=_entry_options_html(entry, calendar, day, month, year),
|
||||||
pre_action=pre_action, edit_url=edit_url)
|
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",
|
label_html = sx_call("events-entry-label",
|
||||||
entry_id=str(entry.id),
|
entry_id=str(entry.id),
|
||||||
title=SxExpr(_entry_title_html(entry)),
|
title=_entry_title_html(entry),
|
||||||
times=SxExpr(_entry_times_html(entry)))
|
times=SxExpr(_entry_times_html(entry)))
|
||||||
|
|
||||||
nav_html = _entry_nav_html(ctx)
|
nav_html = _entry_nav_html(ctx)
|
||||||
|
|
||||||
return sx_call("menu-row-sx", id="entry-row", level=5,
|
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)
|
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:
|
else:
|
||||||
img_html = sx_call("events-post-img-placeholder")
|
img_html = sx_call("events-post-img-placeholder")
|
||||||
post_links += sx_call("events-entry-nav-post-link",
|
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",
|
parts.append((sx_call("events-entry-posts-nav-oob",
|
||||||
items=SxExpr(post_links))).replace(' :hx-swap-oob "true"', ''))
|
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",
|
return options + sx_call("events-entry-optioned-oob",
|
||||||
entry_id=str(entry.id),
|
entry_id=str(entry.id),
|
||||||
title=SxExpr(title), state=SxExpr(state))
|
title=title, state=state)
|
||||||
|
|
||||||
|
|
||||||
def _entry_title_html(entry) -> str:
|
def _entry_title_html(entry) -> str:
|
||||||
@@ -428,7 +428,7 @@ def _entry_title_html(entry) -> str:
|
|||||||
state = getattr(entry, "state", "pending") or "pending"
|
state = getattr(entry, "state", "pending") or "pending"
|
||||||
return sx_call("events-entry-title",
|
return sx_call("events-entry-title",
|
||||||
name=entry.name,
|
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:
|
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,
|
entry_id=eid, post_id=ep_id,
|
||||||
)
|
)
|
||||||
items += sx_call("events-entry-post-item",
|
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,
|
del_url=del_url, entry_id=eid_s,
|
||||||
csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}')
|
csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}')
|
||||||
posts_html = sx_call("events-entry-posts-list", items=SxExpr(items))
|
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",
|
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)
|
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"))
|
if feat else sx_call("events-post-img-placeholder"))
|
||||||
items += sx_call("events-entry-nav-post",
|
items += sx_call("events-entry-nav-post",
|
||||||
href=href, nav_btn=nav_btn,
|
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))
|
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,
|
return sx_call("menu-row-sx", id="entry-admin-row", level=6,
|
||||||
link_href=link_href, link_label="admin", icon="fa fa-cog",
|
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:
|
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",
|
parts.append(sx_call("events-post-search-item",
|
||||||
post_url=post_url, entry_id=str(eid), csrf=csrf,
|
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)
|
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",
|
html = sx_call("events-entry-edit-form",
|
||||||
entry_id=str(eid), list_container=list_container,
|
entry_id=str(eid), list_container=list_container,
|
||||||
put_url=put_url, cancel_url=cancel_url, csrf=csrf,
|
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,
|
start_val=start_val, end_val=end_val, cost_display=cost_display,
|
||||||
ticket_price_val=tp_val, ticket_count_val=tc_val,
|
ticket_price_val=tp_val, ticket_count_val=tc_val,
|
||||||
action_btn=action_btn, cancel_btn=cancel_btn)
|
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",
|
html = sx_call("events-entry-add-form",
|
||||||
post_url=post_url, csrf=csrf,
|
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,
|
action_btn=action_btn, cancel_btn=cancel_btn,
|
||||||
cancel_url=cancel_url)
|
cancel_url=cancel_url)
|
||||||
return html + _SLOT_PICKER_JS
|
return html + _SLOT_PICKER_JS
|
||||||
@@ -998,13 +998,13 @@ def render_fragment_account_tickets(tickets) -> str:
|
|||||||
items_html += sx_call("events-frag-ticket-item",
|
items_html += sx_call("events-frag-ticket-item",
|
||||||
href=href, entry_name=ticket.entry_name,
|
href=href, entry_name=ticket.entry_name,
|
||||||
date_str=date_str, calendar_name=cal_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))
|
body = sx_call("events-frag-tickets-list", items=SxExpr(items_html))
|
||||||
else:
|
else:
|
||||||
body = sx_call("empty-state", message="No tickets yet.",
|
body = sx_call("empty-state", message="No tickets yet.",
|
||||||
cls="text-sm text-stone-500")
|
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,
|
name=booking.name,
|
||||||
date_str=date_str + date_str_extra,
|
date_str=date_str + date_str_extra,
|
||||||
calendar_name=cal_name, cost_str=cost_str,
|
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))
|
body = sx_call("events-frag-bookings-list", items=SxExpr(items_html))
|
||||||
else:
|
else:
|
||||||
body = sx_call("empty-state", message="No bookings yet.",
|
body = sx_call("empty-state", message="No bookings yet.",
|
||||||
cls="text-sm text-stone-500")
|
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)
|
||||||
|
|||||||
@@ -229,14 +229,13 @@ def _register_events_layouts() -> None:
|
|||||||
|
|
||||||
async def _cal_admin_full(ctx: dict, **kw: Any) -> str:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-cal-admin-layout-full", {},
|
return await render_to_sx_with_env("events-cal-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
calendar_admin_header=SxExpr(_calendar_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-cal-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)),
|
cal_oob=_calendar_header_sx(ctx, oob=True),
|
||||||
cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child",
|
cal_admin_oob_wrap=await oob_header_sx("calendar-header-child",
|
||||||
"calendar-admin-header-child", _calendar_admin_header_sx(ctx))),
|
"calendar-admin-header-child", _calendar_admin_header_sx(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slots-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)),
|
cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
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.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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slot-layout-full", {},
|
return await render_to_sx_with_env("events-slot-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)),
|
calendar_admin_header=_calendar_admin_header_sx(ctx),
|
||||||
slot_header=SxExpr(_slot_header_html(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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slot-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)),
|
cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True),
|
||||||
slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child",
|
slot_oob_wrap=await oob_header_sx("calendar-admin-header-child",
|
||||||
"slot-header-child", _slot_header_html(ctx))),
|
"slot-header-child", _slot_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-day-admin-layout-full", {},
|
return await render_to_sx_with_env("events-day-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
day_admin_header=SxExpr(_day_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-day-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)),
|
cal_oob=_calendar_header_sx(ctx, oob=True),
|
||||||
day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child",
|
day_admin_oob_wrap=await oob_header_sx("day-header-child",
|
||||||
"day-admin-header-child", _day_admin_header_sx(ctx))),
|
"day-admin-header-child", _day_admin_header_sx(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
async def _entry_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-entry-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(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.helpers import render_to_sx_with_env, oob_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
from shared.sx.parser import SxExpr
|
||||||
return await render_to_sx_with_env("events-entry-layout-oob", {},
|
return await render_to_sx_with_env("events-entry-layout-oob", {},
|
||||||
day_oob=SxExpr(_day_header_sx(ctx, oob=True)),
|
day_oob=_day_header_sx(ctx, oob=True),
|
||||||
entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child",
|
entry_oob_wrap=await oob_header_sx("day-header-child",
|
||||||
"entry-header-child", _entry_header_html(ctx))),
|
"entry-header-child", _entry_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"calendar-row", "calendar-header-child",
|
"calendar-row", "calendar-header-child",
|
||||||
"day-row", "day-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:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-entry-admin-layout-full", {},
|
return await render_to_sx_with_env("events-entry-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-entry-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
entry_oob=SxExpr(_entry_header_html(ctx, oob=True)),
|
entry_oob=_entry_header_html(ctx, oob=True),
|
||||||
entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child",
|
entry_admin_oob_wrap=await oob_header_sx("entry-header-child",
|
||||||
"entry-admin-header-child", _entry_admin_header_html(ctx))),
|
"entry-admin-header-child", _entry_admin_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
async def _ticket_types_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-ticket-types-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_header_html(ctx)),
|
entry_admin_header=_entry_admin_header_html(ctx),
|
||||||
ticket_types_header=SxExpr(_ticket_types_header_html(ctx)),
|
ticket_types_header=_ticket_types_header_html(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _ticket_types_oob(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, 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", {},
|
return await render_to_sx_with_env("events-ticket-types-layout-oob", {},
|
||||||
entry_admin_oob=SxExpr(_entry_admin_header_html(ctx, oob=True)),
|
entry_admin_oob=_entry_admin_header_html(ctx, oob=True),
|
||||||
ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child",
|
ticket_types_oob_wrap=await oob_header_sx("entry-admin-header-child",
|
||||||
"ticket_types-header-child", _ticket_types_header_html(ctx))),
|
"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:
|
async def _ticket_type_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-ticket-type-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_header_html(ctx)),
|
entry_admin_header=_entry_admin_header_html(ctx),
|
||||||
ticket_types_header=SxExpr(_ticket_types_header_html(ctx)),
|
ticket_types_header=_ticket_types_header_html(ctx),
|
||||||
ticket_type_header=SxExpr(_ticket_type_header_html(ctx)),
|
ticket_type_header=_ticket_type_header_html(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _ticket_type_oob(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, 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", {},
|
return await render_to_sx_with_env("events-ticket-type-layout-oob", {},
|
||||||
ticket_types_oob=SxExpr(_ticket_types_header_html(ctx, oob=True)),
|
ticket_types_oob=_ticket_types_header_html(ctx, oob=True),
|
||||||
ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child",
|
ticket_type_oob_wrap=await oob_header_sx("ticket_types-header-child",
|
||||||
"ticket_type-header-child", _ticket_type_header_html(ctx))),
|
"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:
|
async def _markets_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-markets-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
markets_header=SxExpr(_markets_header_sx(ctx)),
|
markets_header=_markets_header_sx(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _markets_oob(ctx: dict, **kw: Any) -> str:
|
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.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", {},
|
return await render_to_sx_with_env("events-markets-layout-oob", {},
|
||||||
post_oob=SxExpr(await _post_header_sx(ctx, oob=True)),
|
post_oob=await _post_header_sx(ctx, oob=True),
|
||||||
markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child",
|
markets_oob_wrap=await oob_header_sx("post-header-child",
|
||||||
"markets-header-child", _markets_header_sx(ctx))),
|
"markets-header-child", _markets_header_sx(ctx)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,14 +36,13 @@ def _register_events_layouts() -> None:
|
|||||||
|
|
||||||
async def _cal_admin_full(ctx: dict, **kw: Any) -> str:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-cal-admin-layout-full", {},
|
return await render_to_sx_with_env("events-cal-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
calendar_admin_header=SxExpr(_calendar_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-cal-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)),
|
cal_oob=_calendar_header_sx(ctx, oob=True),
|
||||||
cal_admin_oob_wrap=SxExpr(await oob_header_sx("calendar-header-child",
|
cal_admin_oob_wrap=await oob_header_sx("calendar-header-child",
|
||||||
"calendar-admin-header-child", _calendar_admin_header_sx(ctx))),
|
"calendar-admin-header-child", _calendar_admin_header_sx(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slots-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)),
|
cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
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.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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slot-layout-full", {},
|
return await render_to_sx_with_env("events-slot-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
calendar_admin_header=SxExpr(_calendar_admin_header_sx(ctx)),
|
calendar_admin_header=_calendar_admin_header_sx(ctx),
|
||||||
slot_header=SxExpr(_slot_header_html(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})
|
ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-slot-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_admin_oob=SxExpr(_calendar_admin_header_sx(ctx, oob=True)),
|
cal_admin_oob=_calendar_admin_header_sx(ctx, oob=True),
|
||||||
slot_oob_wrap=SxExpr(await oob_header_sx("calendar-admin-header-child",
|
slot_oob_wrap=await oob_header_sx("calendar-admin-header-child",
|
||||||
"slot-header-child", _slot_header_html(ctx))),
|
"slot-header-child", _slot_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-day-admin-layout-full", {},
|
return await render_to_sx_with_env("events-day-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
day_admin_header=SxExpr(_day_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-day-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
cal_oob=SxExpr(_calendar_header_sx(ctx, oob=True)),
|
cal_oob=_calendar_header_sx(ctx, oob=True),
|
||||||
day_admin_oob_wrap=SxExpr(await oob_header_sx("day-header-child",
|
day_admin_oob_wrap=await oob_header_sx("day-header-child",
|
||||||
"day-admin-header-child", _day_admin_header_sx(ctx))),
|
"day-admin-header-child", _day_admin_header_sx(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
async def _entry_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-entry-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(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.helpers import render_to_sx_with_env, oob_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
from shared.sx.parser import SxExpr
|
||||||
return await render_to_sx_with_env("events-entry-layout-oob", {},
|
return await render_to_sx_with_env("events-entry-layout-oob", {},
|
||||||
day_oob=SxExpr(_day_header_sx(ctx, oob=True)),
|
day_oob=_day_header_sx(ctx, oob=True),
|
||||||
entry_oob_wrap=SxExpr(await oob_header_sx("day-header-child",
|
entry_oob_wrap=await oob_header_sx("day-header-child",
|
||||||
"entry-header-child", _entry_header_html(ctx))),
|
"entry-header-child", _entry_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"calendar-row", "calendar-header-child",
|
"calendar-row", "calendar-header-child",
|
||||||
"day-row", "day-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:
|
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.helpers import render_to_sx_with_env, post_admin_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await _ensure_container_nav(ctx)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-entry-admin-layout-full", {},
|
return await render_to_sx_with_env("events-entry-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
admin_header=SxExpr(await post_admin_header_sx(ctx, slug, selected="calendars")),
|
admin_header=await post_admin_header_sx(ctx, slug, selected="calendars"),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_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)
|
ctx = await _ensure_container_nav(ctx)
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
slug = (ctx.get("post") or {}).get("slug", "")
|
||||||
return await render_to_sx_with_env("events-entry-admin-layout-oob", {},
|
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")),
|
admin_oob=await post_admin_header_sx(ctx, slug, oob=True, selected="calendars"),
|
||||||
entry_oob=SxExpr(_entry_header_html(ctx, oob=True)),
|
entry_oob=_entry_header_html(ctx, oob=True),
|
||||||
entry_admin_oob_wrap=SxExpr(await oob_header_sx("entry-header-child",
|
entry_admin_oob_wrap=await oob_header_sx("entry-header-child",
|
||||||
"entry-admin-header-child", _entry_admin_header_html(ctx))),
|
"entry-admin-header-child", _entry_admin_header_html(ctx)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"post-admin-row", "post-admin-header-child",
|
"post-admin-row", "post-admin-header-child",
|
||||||
"calendar-row", "calendar-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:
|
async def _ticket_types_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-ticket-types-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_header_html(ctx)),
|
entry_admin_header=_entry_admin_header_html(ctx),
|
||||||
ticket_types_header=SxExpr(_ticket_types_header_html(ctx)),
|
ticket_types_header=_ticket_types_header_html(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _ticket_types_oob(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, 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", {},
|
return await render_to_sx_with_env("events-ticket-types-layout-oob", {},
|
||||||
entry_admin_oob=SxExpr(_entry_admin_header_html(ctx, oob=True)),
|
entry_admin_oob=_entry_admin_header_html(ctx, oob=True),
|
||||||
ticket_types_oob_wrap=SxExpr(await oob_header_sx("entry-admin-header-child",
|
ticket_types_oob_wrap=await oob_header_sx("entry-admin-header-child",
|
||||||
"ticket_types-header-child", _ticket_types_header_html(ctx))),
|
"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:
|
async def _ticket_type_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-ticket-type-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
calendar_header=SxExpr(_calendar_header_sx(ctx)),
|
calendar_header=_calendar_header_sx(ctx),
|
||||||
day_header=SxExpr(_day_header_sx(ctx)),
|
day_header=_day_header_sx(ctx),
|
||||||
entry_header=SxExpr(_entry_header_html(ctx)),
|
entry_header=_entry_header_html(ctx),
|
||||||
entry_admin_header=SxExpr(_entry_admin_header_html(ctx)),
|
entry_admin_header=_entry_admin_header_html(ctx),
|
||||||
ticket_types_header=SxExpr(_ticket_types_header_html(ctx)),
|
ticket_types_header=_ticket_types_header_html(ctx),
|
||||||
ticket_type_header=SxExpr(_ticket_type_header_html(ctx)),
|
ticket_type_header=_ticket_type_header_html(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _ticket_type_oob(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, 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", {},
|
return await render_to_sx_with_env("events-ticket-type-layout-oob", {},
|
||||||
ticket_types_oob=SxExpr(_ticket_types_header_html(ctx, oob=True)),
|
ticket_types_oob=_ticket_types_header_html(ctx, oob=True),
|
||||||
ticket_type_oob_wrap=SxExpr(await oob_header_sx("ticket_types-header-child",
|
ticket_type_oob_wrap=await oob_header_sx("ticket_types-header-child",
|
||||||
"ticket_type-header-child", _ticket_type_header_html(ctx))),
|
"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:
|
async def _markets_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_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", {},
|
return await render_to_sx_with_env("events-markets-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
markets_header=SxExpr(_markets_header_sx(ctx)),
|
markets_header=_markets_header_sx(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _markets_oob(ctx: dict, **kw: Any) -> str:
|
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.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", {},
|
return await render_to_sx_with_env("events-markets-layout-oob", {},
|
||||||
post_oob=SxExpr(await _post_header_sx(ctx, oob=True)),
|
post_oob=await _post_header_sx(ctx, oob=True),
|
||||||
markets_oob_wrap=SxExpr(await oob_header_sx("post-header-child",
|
markets_oob_wrap=await oob_header_sx("post-header-child",
|
||||||
"markets-header-child", _markets_header_sx(ctx))),
|
"markets-header-child", _markets_header_sx(ctx)),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ def _slot_header_html(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
name=slot.name, description=desc)
|
name=slot.name, description=desc)
|
||||||
|
|
||||||
return sx_call("menu-row-sx", id="slot-row", level=5,
|
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)
|
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",
|
result = sx_call("events-slot-panel",
|
||||||
slot_id=sid, list_container=list_container,
|
slot_id=sid, list_container=list_container,
|
||||||
days=SxExpr(days_html),
|
days=days_html,
|
||||||
flexible="yes" if flexible else "no",
|
flexible="yes" if flexible else "no",
|
||||||
time_str=f"{time_start} \u2014 {time_end}",
|
time_str=f"{time_start} \u2014 {time_end}",
|
||||||
cost_str=cost_str,
|
cost_str=cost_str,
|
||||||
@@ -259,7 +259,7 @@ def render_slots_table(slots, calendar) -> str:
|
|||||||
pill_cls=pill_cls, hx_select=hx_select,
|
pill_cls=pill_cls, hx_select=hx_select,
|
||||||
slot_name=s.name, description=desc,
|
slot_name=s.name, description=desc,
|
||||||
flexible="yes" if s.flexible else "no",
|
flexible="yes" if s.flexible else "no",
|
||||||
days=SxExpr(days_html),
|
days=days_html,
|
||||||
time_str=f"{time_start} - {time_end}",
|
time_str=f"{time_start} - {time_end}",
|
||||||
cost_str=cost_str, action_btn=action_btn,
|
cost_str=cost_str, action_btn=action_btn,
|
||||||
del_url=del_url,
|
del_url=del_url,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ def _ticket_widget_html(entry, qty: int, ticket_url: str, *, ctx: dict) -> str:
|
|||||||
return sx_call("events-tw-form",
|
return sx_call("events-tw-form",
|
||||||
ticket_url=ticket_url, target=tgt,
|
ticket_url=ticket_url, target=tgt,
|
||||||
csrf=csrf_token_val, entry_id=str(eid),
|
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:
|
if qty == 0:
|
||||||
inner = _tw_form(1, sx_call("events-tw-cart-plus"))
|
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,
|
type_name=tt.name if tt else None,
|
||||||
time_str=time_str or None,
|
time_str=time_str or None,
|
||||||
cal_name=cal.name if cal else 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]))
|
code_prefix=ticket.code[:8]))
|
||||||
|
|
||||||
cards_html = "".join(ticket_cards)
|
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",
|
entry_name=entry.name if entry else "\u2014",
|
||||||
date=SxExpr(date_html),
|
date=SxExpr(date_html),
|
||||||
type_name=tt.name if tt else "\u2014",
|
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))
|
action=SxExpr(action_html))
|
||||||
|
|
||||||
return sx_call("events-ticket-admin-panel",
|
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",
|
entry_name=entry.name if entry else "\u2014",
|
||||||
date=SxExpr(date_html),
|
date=SxExpr(date_html),
|
||||||
type_name=tt.name if tt else "\u2014",
|
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)
|
time_str=time_str)
|
||||||
|
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ def render_lookup_result(ticket, error: str | None) -> str:
|
|||||||
if cal:
|
if cal:
|
||||||
info_html += sx_call("events-lookup-cal", cal_name=cal.name)
|
info_html += sx_call("events-lookup-cal", cal_name=cal.name)
|
||||||
info_html += sx_call("events-lookup-status",
|
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:
|
if checked_in_at:
|
||||||
info_html += sx_call("events-lookup-checkin-time",
|
info_html += sx_call("events-lookup-checkin-time",
|
||||||
date_str=checked_in_at.strftime("%B %d, %Y at %H:%M"))
|
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",
|
rows_html += sx_call("events-entry-tickets-admin-row",
|
||||||
code=code, code_short=code[:12] + "...",
|
code=code, code_short=code[:12] + "...",
|
||||||
type_name=tt.name if tt else "\u2014",
|
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))
|
action=SxExpr(action_html))
|
||||||
|
|
||||||
if tickets:
|
if tickets:
|
||||||
@@ -340,7 +340,7 @@ def render_entry_tickets_admin(entry, tickets: list) -> str:
|
|||||||
return sx_call("events-entry-tickets-admin-panel",
|
return sx_call("events-entry-tickets-admin-panel",
|
||||||
entry_name=entry.name,
|
entry_name=entry.name,
|
||||||
count_label=f"{count} ticket{suffix}",
|
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"
|
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_items += sx_call("events-buy-type-item",
|
||||||
type_name=tt.name, cost_str=cost_str,
|
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))
|
body_html = sx_call("events-buy-types-wrapper", items=SxExpr(type_items))
|
||||||
else:
|
else:
|
||||||
qty = user_ticket_count or 0
|
qty = user_ticket_count or 0
|
||||||
body_html = sx_call("events-buy-default",
|
body_html = sx_call("events-buy-default",
|
||||||
price_str=f"\u00a3{tp:.2f}",
|
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",
|
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):
|
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",
|
return sx_call("events-adjust-form",
|
||||||
adjust_url=adjust_url, target=target,
|
adjust_url=adjust_url, target=target,
|
||||||
extra_cls=extra_cls, csrf=csrf,
|
extra_cls=extra_cls, csrf=csrf,
|
||||||
entry_id=eid_s, tt=SxExpr(tt_html) if tt_html else None,
|
entry_id=eid_s, tt=tt_html or None,
|
||||||
count_val=str(count_val), btn=SxExpr(btn_html))
|
count_val=str(count_val), btn=btn_html)
|
||||||
|
|
||||||
if count == 0:
|
if count == 0:
|
||||||
return _adj_form(1, sx_call("events-adjust-cart-plus"),
|
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"))
|
plus = _adj_form(count + 1, sx_call("events-adjust-plus"))
|
||||||
|
|
||||||
return sx_call("events-adjust-controls",
|
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,
|
return sx_call("menu-row-sx", id="ticket_types-row", level=7,
|
||||||
link_href=link_href, link_label_content=SxExpr(label_html),
|
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,
|
return sx_call("menu-row-sx", id="ticket_type-row", level=8,
|
||||||
link_href=link_href, link_label_content=SxExpr(label_html),
|
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)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from shared.sx.helpers import sx_call
|
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,
|
list_href=list_href, tile_href=tile_href,
|
||||||
hx_select=hx_select, list_cls=list_active,
|
hx_select=hx_select, list_cls=list_active,
|
||||||
tile_cls=tile_active, storage_key="events_view",
|
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:
|
def _cart_icon_oob(count: int) -> str:
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ async def _render_choose_username(*, actor=None, error="", username=""):
|
|||||||
from shared.browser.app.csrf import generate_csrf_token
|
from shared.browser.app.csrf import generate_csrf_token
|
||||||
from shared.config import config
|
from shared.config import config
|
||||||
from shared.sx.helpers import sx_call
|
from shared.sx.helpers import sx_call
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
from shared.sx.page import get_template_context
|
from shared.sx.page import get_template_context
|
||||||
from sxc.pages.utils import _social_page
|
from sxc.pages.utils import _social_page
|
||||||
from markupsafe import escape
|
from markupsafe import escape
|
||||||
@@ -45,7 +44,7 @@ async def _render_choose_username(*, actor=None, error="", username=""):
|
|||||||
content = sx_call(
|
content = sx_call(
|
||||||
"federation-choose-username",
|
"federation-choose-username",
|
||||||
domain=str(escape(ap_domain)),
|
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)),
|
csrf=csrf, username=str(escape(username)),
|
||||||
check_url=check_url,
|
check_url=check_url,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -212,7 +212,6 @@ def register(url_prefix="/social"):
|
|||||||
"""Re-render interaction buttons after a like/boost action."""
|
"""Re-render interaction buttons after a like/boost action."""
|
||||||
from shared.models.federation import APInteraction
|
from shared.models.federation import APInteraction
|
||||||
from shared.browser.app.csrf import generate_csrf_token
|
from shared.browser.app.csrf import generate_csrf_token
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
svc = services.federation
|
svc = services.federation
|
||||||
@@ -290,9 +289,9 @@ def register(url_prefix="/social"):
|
|||||||
count=str(boost_count))
|
count=str(boost_count))
|
||||||
|
|
||||||
return sx_response(sx_call("federation-interaction-buttons",
|
return sx_response(sx_call("federation-interaction-buttons",
|
||||||
like=SxExpr(like_form),
|
like=like_form,
|
||||||
boost=SxExpr(boost_form),
|
boost=boost_form,
|
||||||
reply=SxExpr(reply_sx) if reply_sx else None))
|
reply=reply_sx or None))
|
||||||
|
|
||||||
# -- Following / Followers pagination --------------------------------------
|
# -- Following / Followers pagination --------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Federation link-card fragment handler
|
;; Federation link-card fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders actor profile preview card(s) by username.
|
;; Renders actor profile preview card(s) by username.
|
||||||
;; Supports single mode (?slug=x or ?username=x) and batch mode (?keys=x,y,z).
|
;; Supports single mode (?slug=x or ?username=x) and batch mode (?keys=x,y,z).
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Market container-nav fragment handler
|
;; Market container-nav fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders marketplace link nav items for blog post pages.
|
;; Renders marketplace link nav items for blog post pages.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Market link-card fragment handler
|
;; Market link-card fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders product preview card(s) by slug.
|
;; Renders product preview card(s) by slug.
|
||||||
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
;; Supports single mode (?slug=x) and batch mode (?keys=x,y,z).
|
||||||
|
|||||||
@@ -188,9 +188,9 @@ def _market_card_sx(market: Any, page_info: dict, *, show_page_badge: bool = Tru
|
|||||||
|
|
||||||
return sx_call(
|
return sx_call(
|
||||||
"market-market-card",
|
"market-market-card",
|
||||||
title_content=SxExpr(title_sx) if title_sx else None,
|
title_content=title_sx or None,
|
||||||
desc_content=SxExpr(desc_sx) if desc_sx else None,
|
desc_content=desc_sx or None,
|
||||||
badge_content=SxExpr(badge_sx) if badge_sx else None,
|
badge_content=badge_sx or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ async def _desktop_filter_sx(ctx: dict) -> str:
|
|||||||
if brands:
|
if brands:
|
||||||
brand_inner = _brand_filter_sx(brands, selected_brands, ctx)
|
brand_inner = _brand_filter_sx(brands, selected_brands, ctx)
|
||||||
brand_summary = sx_call("market-desktop-brand-summary",
|
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]) + ")"
|
return "(<> " + " ".join([search_sx, cat_summary, brand_summary]) + ")"
|
||||||
|
|
||||||
@@ -226,8 +226,8 @@ async def _mobile_filter_summary_sx(ctx: dict) -> str:
|
|||||||
|
|
||||||
return sx_call(
|
return sx_call(
|
||||||
"market-mobile-filter-summary",
|
"market-mobile-filter-summary",
|
||||||
search_bar=SxExpr(search_bar),
|
search_bar=search_bar,
|
||||||
chips=SxExpr(chips_row),
|
chips=chips_row,
|
||||||
filter=SxExpr(mobile_filter),
|
filter=SxExpr(mobile_filter),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -151,10 +151,9 @@ async def _h_page_markets_content(slug=None, **kw):
|
|||||||
async def _h_page_admin_content(slug=None, **kw):
|
async def _h_page_admin_content(slug=None, **kw):
|
||||||
from shared.sx.page import get_template_context
|
from shared.sx.page import get_template_context
|
||||||
from shared.sx.helpers import sx_call
|
from shared.sx.helpers import sx_call
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
ctx = await get_template_context()
|
ctx = await get_template_context()
|
||||||
content = await _markets_admin_panel_sx(ctx)
|
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):
|
def _h_market_home_content(page_slug=None, market_slug=None, **kw):
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ def _market_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
return sx_call(
|
return sx_call(
|
||||||
"menu-row-sx",
|
"menu-row-sx",
|
||||||
id="market-row", level=2,
|
id="market-row", level=2,
|
||||||
link_href=link_href, link_label_content=SxExpr(label_sx),
|
link_href=link_href, link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
nav=nav_sx or None,
|
||||||
child_id="market-header-child", oob=oob,
|
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",
|
return sx_call("market-desktop-category-nav",
|
||||||
links=SxExpr(links_sx),
|
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:
|
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(
|
return sx_call(
|
||||||
"menu-row-sx",
|
"menu-row-sx",
|
||||||
id="product-row", level=3,
|
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,
|
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,
|
bg_cls=bg_cls, href=cat_href, hx_select=hx_select,
|
||||||
select_colours=select_colours, cat_name=cat,
|
select_colours=select_colours, cat_name=cat,
|
||||||
count_label=f"{cat_count} products", count_str=str(cat_count),
|
count_label=f"{cat_count} products", count_str=str(cat_count),
|
||||||
chevron=SxExpr(chevron_sx),
|
chevron=chevron_sx,
|
||||||
)
|
)
|
||||||
|
|
||||||
subs = data.get("subs", [])
|
subs = data.get("subs", [])
|
||||||
@@ -246,8 +246,8 @@ def _mobile_nav_panel_sx(ctx: dict) -> str:
|
|||||||
item_parts.append(sx_call(
|
item_parts.append(sx_call(
|
||||||
"market-mobile-cat-details",
|
"market-mobile-cat-details",
|
||||||
open=cat_active or None,
|
open=cat_active or None,
|
||||||
summary=SxExpr(summary_sx),
|
summary=summary_sx,
|
||||||
subs=SxExpr(subs_sx),
|
subs=subs_sx,
|
||||||
))
|
))
|
||||||
|
|
||||||
items_sx = "(<> " + " ".join(item_parts) + ")"
|
items_sx = "(<> " + " ".join(item_parts) + ")"
|
||||||
@@ -295,16 +295,16 @@ def _register_market_layouts() -> None:
|
|||||||
async def _market_full(ctx: dict, **kw: Any) -> str:
|
async def _market_full(ctx: dict, **kw: Any) -> str:
|
||||||
from shared.sx.helpers import render_to_sx_with_env
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
return await render_to_sx_with_env("market-browse-layout-full", {},
|
return await render_to_sx_with_env("market-browse-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
market_header=SxExpr(_market_header_sx(ctx)))
|
market_header=_market_header_sx(ctx))
|
||||||
|
|
||||||
|
|
||||||
async def _market_oob(ctx: dict, **kw: Any) -> str:
|
async def _market_oob(ctx: dict, **kw: Any) -> str:
|
||||||
oob_hdr = await _oob_header_sx("post-header-child", "market-header-child",
|
oob_hdr = await _oob_header_sx("post-header-child", "market-header-child",
|
||||||
_market_header_sx(ctx))
|
_market_header_sx(ctx))
|
||||||
return sx_call("market-browse-layout-oob",
|
return sx_call("market-browse-layout-oob",
|
||||||
oob_header=SxExpr(oob_hdr),
|
oob_header=oob_hdr,
|
||||||
post_header_oob=SxExpr(await _post_header_sx(ctx, oob=True)),
|
post_header_oob=await _post_header_sx(ctx, oob=True),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"market-row", "market-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
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
selected = kw.get("selected", "")
|
selected = kw.get("selected", "")
|
||||||
return await render_to_sx_with_env("market-admin-layout-full", {},
|
return await render_to_sx_with_env("market-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
market_header=SxExpr(_market_header_sx(ctx)),
|
market_header=_market_header_sx(ctx),
|
||||||
admin_header=SxExpr(await _market_admin_header_sx(ctx, selected=selected)))
|
admin_header=await _market_admin_header_sx(ctx, selected=selected))
|
||||||
|
|
||||||
|
|
||||||
async def _market_admin_oob(ctx: dict, **kw: Any) -> str:
|
async def _market_admin_oob(ctx: dict, **kw: Any) -> str:
|
||||||
selected = kw.get("selected", "")
|
selected = kw.get("selected", "")
|
||||||
return sx_call("market-admin-layout-oob",
|
return sx_call("market-admin-layout-oob",
|
||||||
market_header_oob=SxExpr(_market_header_sx(ctx, oob=True)),
|
market_header_oob=_market_header_sx(ctx, oob=True),
|
||||||
admin_oob_header=SxExpr(await _oob_header_sx("market-header-child", "market-admin-header-child",
|
admin_oob_header=await _oob_header_sx("market-header-child", "market-admin-header-child",
|
||||||
await _market_admin_header_sx(ctx, selected=selected))),
|
await _market_admin_header_sx(ctx, selected=selected)),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"market-row", "market-header-child",
|
"market-row", "market-header-child",
|
||||||
"market-admin-row", "market-admin-header-child")))
|
"market-admin-row", "market-admin-header-child")))
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ async def render_browse_page(ctx: dict) -> str:
|
|||||||
|
|
||||||
from shared.sx.helpers import render_to_sx_with_env
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
hdr = await render_to_sx_with_env("market-browse-layout-full", {},
|
hdr = await render_to_sx_with_env("market-browse-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
market_header=SxExpr(_market_header_sx(ctx)))
|
market_header=_market_header_sx(ctx))
|
||||||
menu = _mobile_nav_panel_sx(ctx)
|
menu = _mobile_nav_panel_sx(ctx)
|
||||||
filter_sx = await _mobile_filter_summary_sx(ctx)
|
filter_sx = await _mobile_filter_summary_sx(ctx)
|
||||||
aside_sx = await _desktop_filter_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",
|
oob_hdr = await _oob_header_sx("post-header-child", "market-header-child",
|
||||||
_market_header_sx(ctx))
|
_market_header_sx(ctx))
|
||||||
oobs = sx_call("market-browse-layout-oob",
|
oobs = sx_call("market-browse-layout-oob",
|
||||||
oob_header=SxExpr(oob_hdr),
|
oob_header=oob_hdr,
|
||||||
post_header_oob=SxExpr(await _post_header_sx(ctx, oob=True)),
|
post_header_oob=await _post_header_sx(ctx, oob=True),
|
||||||
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
clear_oob=SxExpr(_clear_deeper_oob("post-row", "post-header-child",
|
||||||
"market-row", "market-header-child")))
|
"market-row", "market-header-child")))
|
||||||
menu = _mobile_nav_panel_sx(ctx)
|
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
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
hdr = await render_to_sx_with_env("market-product-layout-full", {},
|
hdr = await render_to_sx_with_env("market-product-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
market_header=SxExpr(_market_header_sx(ctx)),
|
market_header=_market_header_sx(ctx),
|
||||||
product_header=SxExpr(_product_header_sx(ctx, d)))
|
product_header=_product_header_sx(ctx, d))
|
||||||
return await full_page_sx(ctx, header_rows=hdr, content=content, meta=meta)
|
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
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
hdr = await render_to_sx_with_env("market-product-admin-layout-full", {},
|
hdr = await render_to_sx_with_env("market-product-admin-layout-full", {},
|
||||||
post_header=SxExpr(await _post_header_sx(ctx)),
|
post_header=await _post_header_sx(ctx),
|
||||||
market_header=SxExpr(_market_header_sx(ctx)),
|
market_header=_market_header_sx(ctx),
|
||||||
product_header=SxExpr(_product_header_sx(ctx, d)),
|
product_header=_product_header_sx(ctx, d),
|
||||||
admin_header=SxExpr(_product_admin_header_sx(ctx, d)))
|
admin_header=_product_admin_header_sx(ctx, d))
|
||||||
return await full_page_sx(ctx, header_rows=hdr, content=content)
|
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(
|
add_sx = sx_call(
|
||||||
"market-cart-add-oob",
|
"market-cart-add-oob",
|
||||||
id=f"cart-add-{slug}",
|
id=f"cart-add-{slug}",
|
||||||
inner=SxExpr(cart_add),
|
inner=cart_add,
|
||||||
)
|
)
|
||||||
|
|
||||||
return "(<> " + cart_mini + " " + add_sx + ")"
|
return "(<> " + cart_mini + " " + add_sx + ")"
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ def _product_detail_sx(d: dict, ctx: dict) -> str:
|
|||||||
|
|
||||||
gallery_inner = sx_call(
|
gallery_inner = sx_call(
|
||||||
"market-detail-gallery-inner",
|
"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", ""),
|
image=images[0], alt=d.get("title", ""),
|
||||||
labels=SxExpr(labels_sx) if labels_sx else None,
|
labels=SxExpr(labels_sx) if labels_sx else None,
|
||||||
brand=brand,
|
brand=brand,
|
||||||
@@ -123,8 +123,8 @@ def _product_detail_sx(d: dict, ctx: dict) -> str:
|
|||||||
|
|
||||||
gallery_sx = sx_call(
|
gallery_sx = sx_call(
|
||||||
"market-detail-gallery",
|
"market-detail-gallery",
|
||||||
inner=SxExpr(gallery_inner),
|
inner=gallery_inner,
|
||||||
nav=SxExpr(nav_buttons) if nav_buttons else None,
|
nav=nav_buttons or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Thumbnails
|
# Thumbnails
|
||||||
@@ -144,7 +144,7 @@ def _product_detail_sx(d: dict, ctx: dict) -> str:
|
|||||||
if user:
|
if user:
|
||||||
like_sx = _like_button_sx(slug, liked_by_current_user, csrf, ctx)
|
like_sx = _like_button_sx(slug, liked_by_current_user, csrf, ctx)
|
||||||
gallery_final = sx_call("market-detail-no-image",
|
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 below gallery
|
||||||
stickers_sx = ""
|
stickers_sx = ""
|
||||||
@@ -206,8 +206,8 @@ def _product_detail_sx(d: dict, ctx: dict) -> str:
|
|||||||
return sx_call(
|
return sx_call(
|
||||||
"market-detail-layout",
|
"market-detail-layout",
|
||||||
gallery=SxExpr(gallery_final),
|
gallery=SxExpr(gallery_final),
|
||||||
stickers=SxExpr(stickers_sx) if stickers_sx else None,
|
stickers=stickers_sx or None,
|
||||||
details=SxExpr(details_sx),
|
details=details_sx,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ async def _render_checkout_return(ctx: dict, order=None, status: str = "",
|
|||||||
else:
|
else:
|
||||||
img = sx_call("order-item-no-image")
|
img = sx_call("order-item-no-image")
|
||||||
item_parts.append(sx_call("order-item-row",
|
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",
|
title=item.product_title or "Unknown product",
|
||||||
pid=f"Product ID: {item.product_id}",
|
pid=f"Product ID: {item.product_id}",
|
||||||
qty=f"Qty: {item.quantity}",
|
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")
|
status_msg = sx_call("checkout-return-paid")
|
||||||
|
|
||||||
content = sx_call("checkout-return-content",
|
content = sx_call("checkout-return-content",
|
||||||
summary=SxExpr(summary),
|
summary=summary,
|
||||||
items=SxExpr(items) if items else None,
|
items=items or None,
|
||||||
calendar=SxExpr(calendar) if calendar else None,
|
calendar=calendar or None,
|
||||||
tickets=SxExpr(tickets) if tickets else None,
|
tickets=tickets or None,
|
||||||
status_message=SxExpr(status_msg) if status_msg else None,
|
status_message=status_msg or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
account_url = call_url(ctx, "account_url", "")
|
account_url = call_url(ctx, "account_url", "")
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ def register() -> Blueprint:
|
|||||||
if not hosted_url:
|
if not hosted_url:
|
||||||
from shared.sx.page import get_template_context
|
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.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
|
from shared.infrastructure.urls import cart_url
|
||||||
tctx = await get_template_context()
|
tctx = await get_template_context()
|
||||||
account_url = call_url(tctx, "account_url", "")
|
account_url = call_url(tctx, "account_url", "")
|
||||||
@@ -82,7 +81,7 @@ def register() -> Blueprint:
|
|||||||
content = sx_call(
|
content = sx_call(
|
||||||
"checkout-error-content",
|
"checkout-error-content",
|
||||||
msg="No hosted checkout URL returned from SumUp when trying to reopen payment.",
|
msg="No hosted checkout URL returned from SumUp when trying to reopen payment.",
|
||||||
order=SxExpr(order_sx),
|
order=order_sx,
|
||||||
back_url=cart_url("/"),
|
back_url=cart_url("/"),
|
||||||
)
|
)
|
||||||
html = await full_page_sx(tctx, header_rows=hdr, filter=filt, content=content)
|
html = await full_page_sx(tctx, header_rows=hdr, filter=filt, content=content)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Orders account-nav-item fragment handler
|
;; Orders account-nav-item fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Renders the "orders" link for the account dashboard nav.
|
;; Renders the "orders" link for the account dashboard nav.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
;; Relations container-nav fragment handler
|
;; Relations container-nav fragment handler
|
||||||
|
;; returns: sx
|
||||||
;;
|
;;
|
||||||
;; Generic navigation fragment driven by the relation registry.
|
;; Generic navigation fragment driven by the relation registry.
|
||||||
;; Renders nav items for all related entities of a container.
|
;; Renders nav items for all related entities of a container.
|
||||||
|
|||||||
@@ -1010,10 +1010,10 @@ async def async_eval_to_sx(
|
|||||||
ctx = RequestContext()
|
ctx = RequestContext()
|
||||||
result = await _aser(expr, env, ctx)
|
result = await _aser(expr, env, ctx)
|
||||||
if isinstance(result, SxExpr):
|
if isinstance(result, SxExpr):
|
||||||
return result.source
|
return result
|
||||||
if result is None or result is NIL:
|
if result is None or result is NIL:
|
||||||
return ""
|
return SxExpr("")
|
||||||
return serialize(result)
|
return SxExpr(serialize(result))
|
||||||
|
|
||||||
|
|
||||||
async def async_eval_slot_to_sx(
|
async def async_eval_slot_to_sx(
|
||||||
@@ -1039,10 +1039,10 @@ async def async_eval_slot_to_sx(
|
|||||||
if isinstance(comp, Component):
|
if isinstance(comp, Component):
|
||||||
result = await _aser_component(comp, expr[1:], env, ctx)
|
result = await _aser_component(comp, expr[1:], env, ctx)
|
||||||
if isinstance(result, SxExpr):
|
if isinstance(result, SxExpr):
|
||||||
return result.source
|
return result
|
||||||
if result is None or result is NIL:
|
if result is None or result is NIL:
|
||||||
return ""
|
return SxExpr("")
|
||||||
return serialize(result)
|
return SxExpr(serialize(result))
|
||||||
else:
|
else:
|
||||||
import logging
|
import logging
|
||||||
logging.getLogger("sx.eval").error(
|
logging.getLogger("sx.eval").error(
|
||||||
@@ -1056,14 +1056,10 @@ async def async_eval_slot_to_sx(
|
|||||||
# Fall back to normal async_eval_to_sx
|
# Fall back to normal async_eval_to_sx
|
||||||
result = await _aser(expr, env, ctx)
|
result = await _aser(expr, env, ctx)
|
||||||
if isinstance(result, SxExpr):
|
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 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:
|
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."""
|
for everything else."""
|
||||||
if isinstance(expr, (int, float, bool)):
|
if isinstance(expr, (int, float, bool)):
|
||||||
return expr
|
return expr
|
||||||
if isinstance(expr, str):
|
|
||||||
return expr
|
|
||||||
if isinstance(expr, SxExpr):
|
if isinstance(expr, SxExpr):
|
||||||
return expr
|
return expr
|
||||||
|
if isinstance(expr, str):
|
||||||
|
return expr
|
||||||
if expr is None or expr is NIL:
|
if expr is None or expr is NIL:
|
||||||
return NIL
|
return NIL
|
||||||
|
|
||||||
|
|||||||
@@ -111,16 +111,19 @@ async def execute_handler(
|
|||||||
service_name: str,
|
service_name: str,
|
||||||
args: dict[str, str] | None = None,
|
args: dict[str, str] | None = None,
|
||||||
) -> str:
|
) -> 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``,
|
Uses the async evaluator so I/O primitives (``query``, ``service``,
|
||||||
``service``, ``request-arg``, etc.) are awaited inline within
|
``request-arg``, etc.) are awaited inline within control flow.
|
||||||
control flow — no collect-then-substitute limitations.
|
|
||||||
|
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
|
1. Build env from component env + handler closure
|
||||||
2. Bind handler params from args (typically request.args)
|
2. Bind handler params from args (typically request.args)
|
||||||
3. Evaluate + render via async_render (handles I/O inline)
|
3. Evaluate via ``async_eval_to_sx`` (I/O inline, components serialized)
|
||||||
4. Return rendered string
|
4. Return ``SxExpr`` wire format
|
||||||
"""
|
"""
|
||||||
from .jinja_bridge import get_component_env, _get_request_context
|
from .jinja_bridge import get_component_env, _get_request_context
|
||||||
from .async_eval import async_eval_to_sx
|
from .async_eval import async_eval_to_sx
|
||||||
|
|||||||
@@ -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)."""
|
"""Assemble mobile menu from pre-built sections (deepest first)."""
|
||||||
parts = [s for s in sections if s]
|
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:
|
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
|
# 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
|
"""Build post-level nav items (container_nav + admin cog). Shared by
|
||||||
``post_header_sx`` (desktop) and ``post_mobile_nav_sx`` (mobile)."""
|
``post_header_sx`` (desktop) and ``post_mobile_nav_sx`` (mobile)."""
|
||||||
post = ctx.get("post") or {}
|
post = ctx.get("post") or {}
|
||||||
slug = post.get("slug", "")
|
slug = post.get("slug", "")
|
||||||
if not slug:
|
if not slug:
|
||||||
return ""
|
return SxExpr("")
|
||||||
parts: list[str] = []
|
parts: list[str] = []
|
||||||
page_cart_count = ctx.get("page_cart_count", 0)
|
page_cart_count = ctx.get("page_cart_count", 0)
|
||||||
if page_cart_count and 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)
|
is_admin_page=is_admin_page or None)
|
||||||
if admin_nav:
|
if admin_nav:
|
||||||
parts.append(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,
|
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
|
"""Build post-admin nav items (calendars, markets, etc.). Shared by
|
||||||
``post_admin_header_sx`` (desktop) and mobile menu."""
|
``post_admin_header_sx`` (desktop) and mobile menu."""
|
||||||
select_colours = ctx.get("select_colours", "")
|
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,
|
parts.append(await _render_to_sx("nav-link", href=href, label=label,
|
||||||
select_colours=select_colours,
|
select_colours=select_colours,
|
||||||
is_selected=is_sel or None))
|
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,
|
label=title,
|
||||||
href=call_url(ctx, "blog_url", f"/{slug}/"),
|
href=call_url(ctx, "blog_url", f"/{slug}/"),
|
||||||
level=1,
|
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",
|
return await _render_to_sx("menu-row-sx",
|
||||||
id="post-row", level=1,
|
id="post-row", level=1,
|
||||||
link_href=link_href,
|
link_href=link_href,
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
nav=nav_sx,
|
||||||
child_id="post-header-child",
|
child_id="post-header-child",
|
||||||
child=SxExpr(child) if child else None,
|
child=SxExpr(child) if child else None,
|
||||||
oob=oob, external=True,
|
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",
|
return await _render_to_sx("menu-row-sx",
|
||||||
id="post-admin-row", level=2,
|
id="post-admin-row", level=2,
|
||||||
link_href=admin_href,
|
link_href=admin_href,
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
nav=nav_sx,
|
||||||
child_id="post-admin-header-child", oob=oob,
|
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 = dict(get_component_env())
|
||||||
env.update(extra_env)
|
env.update(extra_env)
|
||||||
ctx = _get_request_context()
|
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:
|
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)
|
ast = _build_component_ast(__name, **kwargs)
|
||||||
env = dict(get_component_env())
|
env = dict(get_component_env())
|
||||||
ctx = _get_request_context()
|
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.
|
# 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) + ")")
|
parts.append("(list " + " ".join(items) + ")")
|
||||||
else:
|
else:
|
||||||
parts.append(serialize(val))
|
parts.append(serialize(val))
|
||||||
return "(" + " ".join(parts) + ")"
|
return SxExpr("(" + " ".join(parts) + ")")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,31 +25,37 @@ from .types import Keyword, Symbol, NIL
|
|||||||
# SxExpr — pre-built sx source marker
|
# SxExpr — pre-built sx source marker
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class SxExpr:
|
class SxExpr(str):
|
||||||
"""Pre-built sx source that serialize() outputs unquoted.
|
"""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
|
Use this to nest sx call strings inside other sx_call() invocations
|
||||||
without them being quoted as strings::
|
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))
|
# => (~parent :child (~child :x 1))
|
||||||
"""
|
"""
|
||||||
__slots__ = ("source",)
|
|
||||||
|
|
||||||
def __init__(self, source: str):
|
def __new__(cls, source: str = "") -> "SxExpr":
|
||||||
self.source = source
|
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:
|
def __repr__(self) -> str:
|
||||||
return f"SxExpr({self.source!r})"
|
return f"SxExpr({str.__repr__(self)})"
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.source
|
|
||||||
|
|
||||||
def __add__(self, other: object) -> "SxExpr":
|
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":
|
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:
|
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):
|
if isinstance(expr, SxExpr):
|
||||||
return expr.source
|
return expr.source
|
||||||
|
|
||||||
|
|||||||
@@ -16,30 +16,27 @@ def _register_sx_layouts() -> None:
|
|||||||
async def _sx_full_headers(ctx: dict, **kw: Any) -> str:
|
async def _sx_full_headers(ctx: dict, **kw: Any) -> str:
|
||||||
"""Full headers for sx home page: root + sx menu row."""
|
"""Full headers for sx home page: root + sx menu row."""
|
||||||
from shared.sx.helpers import render_to_sx_with_env
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
|
|
||||||
main_nav = _main_nav_sx(kw.get("section"))
|
main_nav = _main_nav_sx(kw.get("section"))
|
||||||
sx_row = _sx_header_sx(main_nav)
|
sx_row = _sx_header_sx(main_nav)
|
||||||
return await render_to_sx_with_env("sx-layout-full", {},
|
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:
|
async def _sx_oob_headers(ctx: dict, **kw: Any) -> str:
|
||||||
"""OOB headers for sx home page."""
|
"""OOB headers for sx home page."""
|
||||||
from shared.sx.helpers import render_to_sx_with_env, oob_header_sx
|
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"))
|
main_nav = _main_nav_sx(kw.get("section"))
|
||||||
sx_row = _sx_header_sx(main_nav)
|
sx_row = _sx_header_sx(main_nav)
|
||||||
rows = await render_to_sx_with_env("sx-layout-full", {},
|
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)
|
return await oob_header_sx("root-header-child", "sx-header-child", rows)
|
||||||
|
|
||||||
|
|
||||||
async def _sx_section_full_headers(ctx: dict, **kw: Any) -> str:
|
async def _sx_section_full_headers(ctx: dict, **kw: Any) -> str:
|
||||||
"""Full headers for sx section pages: root + sx row + sub row."""
|
"""Full headers for sx section pages: root + sx row + sub row."""
|
||||||
from shared.sx.helpers import render_to_sx_with_env
|
from shared.sx.helpers import render_to_sx_with_env
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
|
|
||||||
section = kw.get("section", "")
|
section = kw.get("section", "")
|
||||||
sub_label = kw.get("sub_label", 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)
|
sub_row = _sub_row_sx(sub_label, sub_href, sub_nav, selected)
|
||||||
sx_row = _sx_header_sx(main_nav, child=sub_row)
|
sx_row = _sx_header_sx(main_nav, child=sub_row)
|
||||||
return await render_to_sx_with_env("sx-section-layout-full", {},
|
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:
|
async def _sx_section_oob_headers(ctx: dict, **kw: Any) -> str:
|
||||||
"""OOB headers for sx section pages."""
|
"""OOB headers for sx section pages."""
|
||||||
from shared.sx.helpers import render_to_sx_with_env, oob_header_sx
|
from shared.sx.helpers import render_to_sx_with_env, oob_header_sx
|
||||||
from shared.sx.parser import SxExpr
|
|
||||||
|
|
||||||
section = kw.get("section", "")
|
section = kw.get("section", "")
|
||||||
sub_label = kw.get("sub_label", 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)
|
sub_row = _sub_row_sx(sub_label, sub_href, sub_nav, selected)
|
||||||
sx_row = _sx_header_sx(main_nav, child=sub_row)
|
sx_row = _sx_header_sx(main_nav, child=sub_row)
|
||||||
rows = await render_to_sx_with_env("sx-section-layout-full", {},
|
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)
|
return await oob_header_sx("root-header-child", "sx-header-child", rows)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def _sx_header_sx(nav: str | None = None, *, child: str | None = None) -> str:
|
|||||||
return sx_call("menu-row-sx",
|
return sx_call("menu-row-sx",
|
||||||
id="sx-row", level=1, colour="violet",
|
id="sx-row", level=1, colour="violet",
|
||||||
link_href="/", link_label="sx",
|
link_href="/", link_label="sx",
|
||||||
link_label_content=SxExpr(label_sx),
|
link_label_content=label_sx,
|
||||||
nav=SxExpr(nav) if nav else None,
|
nav=SxExpr(nav) if nav else None,
|
||||||
child_id="sx-header-child",
|
child_id="sx-header-child",
|
||||||
child=SxExpr(child) if child else None,
|
child=SxExpr(child) if child else None,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import os
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from shared.sx.jinja_bridge import load_service_components
|
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 test-specific .sx components at import time
|
||||||
load_service_components(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
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",
|
inner = sx_call("test-results-partial",
|
||||||
summary_data=summary_data, sections=sections, has_failures=has_failures)
|
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", {},
|
hdr = await render_to_sx_with_env("test-layout-full", {},
|
||||||
services=_service_list(),
|
services=_service_list(),
|
||||||
active_service=active_service,
|
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",
|
inner = sx_call("test-results-partial",
|
||||||
summary_data=summary_data, sections=sections, has_failures=has_failures)
|
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:
|
async def render_test_detail_page_sx(ctx: dict, test: dict) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user