Migrate all apps to defpage declarative page routes
Replace Python GET page handlers with declarative defpage definitions in .sx files across all 8 apps (sx docs, orders, account, market, cart, federation, events, blog). Each app now has sxc/pages/ with setup functions, layout registrations, page helpers, and .sx defpage declarations. Core infrastructure: add g I/O primitive, PageDef support for auth/layout/ data/content/filter/aside/menu slots, post_author auth level, and custom layout registration. Remove ~1400 lines of render_*_page/render_*_oob boilerplate. Update all endpoint references in routes, sx_components, and templates to defpage_* naming. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,8 @@ from typing import Any, Callable, Awaitable
|
||||
from .helpers import (
|
||||
root_header_sx, post_header_sx, post_admin_header_sx,
|
||||
oob_header_sx, header_child_sx,
|
||||
mobile_menu_sx, mobile_root_nav_sx,
|
||||
post_mobile_nav_sx, post_admin_mobile_nav_sx,
|
||||
)
|
||||
|
||||
|
||||
@@ -26,17 +28,19 @@ from .helpers import (
|
||||
class Layout:
|
||||
"""A named layout that generates header rows for full and OOB rendering."""
|
||||
|
||||
__slots__ = ("name", "_full_fn", "_oob_fn")
|
||||
__slots__ = ("name", "_full_fn", "_oob_fn", "_mobile_fn")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
full_fn: Callable[..., str | Awaitable[str]],
|
||||
oob_fn: Callable[..., str | Awaitable[str]],
|
||||
mobile_fn: Callable[..., str | Awaitable[str]] | None = None,
|
||||
):
|
||||
self.name = name
|
||||
self._full_fn = full_fn
|
||||
self._oob_fn = oob_fn
|
||||
self._mobile_fn = mobile_fn
|
||||
|
||||
async def full_headers(self, ctx: dict, **kwargs: Any) -> str:
|
||||
result = self._full_fn(ctx, **kwargs)
|
||||
@@ -50,6 +54,14 @@ class Layout:
|
||||
result = await result
|
||||
return result
|
||||
|
||||
async def mobile_menu(self, ctx: dict, **kwargs: Any) -> str:
|
||||
if self._mobile_fn is None:
|
||||
return ""
|
||||
result = self._mobile_fn(ctx, **kwargs)
|
||||
if hasattr(result, "__await__"):
|
||||
result = await result
|
||||
return result
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Layout:{self.name}>"
|
||||
|
||||
@@ -113,9 +125,27 @@ def _post_admin_oob(ctx: dict, **kw: Any) -> str:
|
||||
return "(<> " + post_hdr + " " + admin_oob + ")"
|
||||
|
||||
|
||||
register_layout(Layout("root", _root_full, _root_oob))
|
||||
register_layout(Layout("post", _post_full, _post_oob))
|
||||
register_layout(Layout("post-admin", _post_admin_full, _post_admin_oob))
|
||||
def _root_mobile(ctx: dict, **kw: Any) -> str:
|
||||
return mobile_root_nav_sx(ctx)
|
||||
|
||||
|
||||
def _post_mobile(ctx: dict, **kw: Any) -> str:
|
||||
return mobile_menu_sx(post_mobile_nav_sx(ctx), mobile_root_nav_sx(ctx))
|
||||
|
||||
|
||||
def _post_admin_mobile(ctx: dict, **kw: Any) -> str:
|
||||
slug = ctx.get("post", {}).get("slug", "")
|
||||
selected = kw.get("selected", "")
|
||||
return mobile_menu_sx(
|
||||
post_admin_mobile_nav_sx(ctx, slug, selected),
|
||||
post_mobile_nav_sx(ctx),
|
||||
mobile_root_nav_sx(ctx),
|
||||
)
|
||||
|
||||
|
||||
register_layout(Layout("root", _root_full, _root_oob, _root_mobile))
|
||||
register_layout(Layout("post", _post_full, _post_oob, _post_mobile))
|
||||
register_layout(Layout("post-admin", _post_admin_full, _post_admin_oob, _post_admin_mobile))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -127,13 +157,15 @@ _CUSTOM_LAYOUTS: dict[str, tuple] = {} # name → (full_fn, oob_fn)
|
||||
|
||||
def register_custom_layout(name: str,
|
||||
full_fn: Callable[..., str | Awaitable[str]],
|
||||
oob_fn: Callable[..., str | Awaitable[str]]) -> None:
|
||||
oob_fn: Callable[..., str | Awaitable[str]],
|
||||
mobile_fn: Callable[..., str | Awaitable[str]] | None = None) -> None:
|
||||
"""Register a custom layout function.
|
||||
|
||||
Used by services with non-standard header patterns::
|
||||
|
||||
register_custom_layout("sx-section",
|
||||
full_fn=my_full_headers,
|
||||
oob_fn=my_oob_headers)
|
||||
oob_fn=my_oob_headers,
|
||||
mobile_fn=my_mobile_menu)
|
||||
"""
|
||||
register_layout(Layout(name, full_fn, oob_fn))
|
||||
register_layout(Layout(name, full_fn, oob_fn, mobile_fn))
|
||||
|
||||
Reference in New Issue
Block a user