Phase 5: Page layouts as s-expressions — components, fragments, error pages

Add 9 new shared s-expression components (cart-mini, auth-menu,
account-nav-item, calendar-entry-nav, calendar-link-nav, market-link-nav,
post-card, base-shell, error-page) and wire them into all fragment route
handlers. 404/403 error pages now render entirely via s-expressions as a
full-page proof-of-concept, with Jinja fallback on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 15:25:11 +00:00
parent 04419a1ec6
commit 8013317b41
9 changed files with 687 additions and 41 deletions

View File

@@ -10,7 +10,7 @@ Fragments:
from __future__ import annotations
from quart import Blueprint, Response, request, render_template, g
from quart import Blueprint, Response, request, g
from shared.infrastructure.fragments import FRAGMENT_HEADER
@@ -24,6 +24,8 @@ def register():
async def _cart_mini():
from shared.services.registry import services
from shared.infrastructure.urls import blog_url, cart_url
from shared.sexp.jinja_bridge import sexp as render_sexp
user_id = request.args.get("user_id", type=int)
session_id = request.args.get("session_id")
@@ -33,17 +35,18 @@ def register():
)
count = summary.count + summary.calendar_count + summary.ticket_count
oob = request.args.get("oob", "")
return await render_template("fragments/cart_mini.html", cart_count=count, oob=oob)
return render_sexp(
'(~cart-mini :cart-count cart-count :blog-url blog-url :cart-url cart-url :oob oob)',
**{"cart-count": count, "blog-url": blog_url(""), "cart-url": cart_url(""), "oob": oob or None},
)
async def _account_nav_item():
from shared.infrastructure.urls import cart_url
from shared.sexp.jinja_bridge import sexp as render_sexp
href = cart_url("/orders/")
return (
'<div class="relative nav-group">'
f'<a href="{href}" class="justify-center cursor-pointer flex flex-row '
'items-center gap-2 rounded bg-stone-200 text-black p-3" data-hx-disable>'
'orders</a></div>'
return render_sexp(
'(~account-nav-item :href href :label "orders")',
href=cart_url("/orders/"),
)
_handlers = {