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:
@@ -279,11 +279,11 @@ async def _h_post_preview_content(slug=None, **kw):
|
||||
if preview.get("sx_rendered"):
|
||||
rendered_sx = sx_call("blog-preview-rendered", html=preview["sx_rendered"])
|
||||
sections.append(sx_call("blog-preview-section",
|
||||
title="SX Rendered", content=SxExpr(rendered_sx)))
|
||||
title="SX Rendered", content=rendered_sx))
|
||||
if preview.get("lex_rendered"):
|
||||
rendered_sx = sx_call("blog-preview-rendered", html=preview["lex_rendered"])
|
||||
sections.append(sx_call("blog-preview-section",
|
||||
title="Lexical Rendered", content=SxExpr(rendered_sx)))
|
||||
title="Lexical Rendered", content=rendered_sx))
|
||||
|
||||
if not sections:
|
||||
return sx_call("blog-preview-empty")
|
||||
|
||||
@@ -10,7 +10,6 @@ from typing import Any
|
||||
|
||||
def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
||||
from shared.sx.helpers import sx_call
|
||||
from shared.sx.parser import SxExpr
|
||||
from quart import url_for as qurl
|
||||
|
||||
settings_href = qurl("settings.defpage_settings_home")
|
||||
@@ -20,8 +19,8 @@ def _settings_header_sx(ctx: dict, *, oob: bool = False) -> str:
|
||||
return sx_call("menu-row-sx",
|
||||
id="root-settings-row", level=1,
|
||||
link_href=settings_href,
|
||||
link_label_content=SxExpr(label_sx),
|
||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
||||
link_label_content=label_sx,
|
||||
nav=nav_sx or None,
|
||||
child_id="root-settings-header-child", oob=oob)
|
||||
|
||||
|
||||
@@ -41,7 +40,7 @@ def _sub_settings_header_sx(row_id: str, child_id: str, href: str,
|
||||
return sx_call("menu-row-sx",
|
||||
id=row_id, level=2,
|
||||
link_href=href,
|
||||
link_label_content=SxExpr(label_sx),
|
||||
link_label_content=label_sx,
|
||||
nav=SxExpr(nav_sx) if nav_sx else None,
|
||||
child_id=child_id, oob=oob)
|
||||
|
||||
@@ -80,16 +79,14 @@ async def _blog_oob(ctx: dict, **kw: Any) -> str:
|
||||
|
||||
async def _settings_full(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env
|
||||
from shared.sx.parser import SxExpr
|
||||
return await render_to_sx_with_env("settings-layout-full", {},
|
||||
settings_header=SxExpr(_settings_header_sx(ctx)))
|
||||
settings_header=_settings_header_sx(ctx))
|
||||
|
||||
|
||||
async def _settings_oob(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env, oob_header_sx
|
||||
from shared.sx.parser import SxExpr
|
||||
rows = await render_to_sx_with_env("settings-layout-full", {},
|
||||
settings_header=SxExpr(_settings_header_sx(ctx)))
|
||||
settings_header=_settings_header_sx(ctx))
|
||||
return await oob_header_sx("root-header-child", "root-settings-header-child", rows)
|
||||
|
||||
|
||||
@@ -102,26 +99,24 @@ def _settings_mobile(ctx: dict, **kw: Any) -> str:
|
||||
async def _sub_settings_full(ctx: dict, row_id: str, child_id: str,
|
||||
endpoint: str, icon: str, label: str) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env
|
||||
from shared.sx.parser import SxExpr
|
||||
from quart import url_for as qurl
|
||||
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
||||
settings_header=SxExpr(_settings_header_sx(ctx)),
|
||||
sub_header=SxExpr(_sub_settings_header_sx(
|
||||
row_id, child_id, qurl(endpoint), icon, label, ctx)))
|
||||
settings_header=_settings_header_sx(ctx),
|
||||
sub_header=_sub_settings_header_sx(
|
||||
row_id, child_id, qurl(endpoint), icon, label, ctx))
|
||||
|
||||
|
||||
async def _sub_settings_oob(ctx: dict, row_id: str, child_id: str,
|
||||
endpoint: str, icon: str, label: str) -> str:
|
||||
from shared.sx.helpers import oob_header_sx, sx_call
|
||||
from shared.sx.parser import SxExpr
|
||||
from quart import url_for as qurl
|
||||
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
||||
sub_hdr = _sub_settings_header_sx(
|
||||
row_id, child_id, qurl(endpoint), icon, label, ctx)
|
||||
sub_oob = await oob_header_sx("root-settings-header-child", child_id, sub_hdr)
|
||||
return sx_call("sub-settings-layout-oob",
|
||||
settings_header_oob=SxExpr(settings_hdr_oob),
|
||||
sub_header_oob=SxExpr(sub_oob))
|
||||
settings_header_oob=settings_hdr_oob,
|
||||
sub_header_oob=sub_oob)
|
||||
|
||||
|
||||
# --- Cache ---
|
||||
@@ -177,20 +172,18 @@ async def _tag_groups_oob(ctx: dict, **kw: Any) -> str:
|
||||
async def _tag_group_edit_full(ctx: dict, **kw: Any) -> str:
|
||||
from quart import request, url_for as qurl
|
||||
from shared.sx.helpers import render_to_sx_with_env
|
||||
from shared.sx.parser import SxExpr
|
||||
g_id = (request.view_args or {}).get("id")
|
||||
return await render_to_sx_with_env("sub-settings-layout-full", {},
|
||||
settings_header=SxExpr(_settings_header_sx(ctx)),
|
||||
sub_header=SxExpr(_sub_settings_header_sx(
|
||||
settings_header=_settings_header_sx(ctx),
|
||||
sub_header=_sub_settings_header_sx(
|
||||
"tag-groups-row", "tag-groups-header-child",
|
||||
qurl("defpage_tag_group_edit", id=g_id),
|
||||
"tags", "Tag Groups", ctx)))
|
||||
"tags", "Tag Groups", ctx))
|
||||
|
||||
|
||||
async def _tag_group_edit_oob(ctx: dict, **kw: Any) -> str:
|
||||
from quart import request, url_for as qurl
|
||||
from shared.sx.helpers import oob_header_sx, sx_call
|
||||
from shared.sx.parser import SxExpr
|
||||
g_id = (request.view_args or {}).get("id")
|
||||
settings_hdr_oob = _settings_header_sx(ctx, oob=True)
|
||||
sub_hdr = _sub_settings_header_sx(
|
||||
@@ -199,5 +192,5 @@ async def _tag_group_edit_oob(ctx: dict, **kw: Any) -> str:
|
||||
"tags", "Tag Groups", ctx)
|
||||
sub_oob = await oob_header_sx("root-settings-header-child", "tag-groups-header-child", sub_hdr)
|
||||
return sx_call("sub-settings-layout-oob",
|
||||
settings_header_oob=SxExpr(settings_hdr_oob),
|
||||
sub_header_oob=SxExpr(sub_oob))
|
||||
settings_header_oob=settings_hdr_oob,
|
||||
sub_header_oob=sub_oob)
|
||||
|
||||
Reference in New Issue
Block a user