Send all responses as sexp wire format with client-side rendering
- Server sends sexp source text, client (sexp.js) renders everything - SexpExpr marker class for nested sexp composition in serialize() - sexp_page() HTML shell with data-mount="body" for full page loads - sexp_response() returns text/sexp for OOB/partial responses - ~app-body layout component replaces ~app-layout (no raw!) - ~rich-text is the only component using raw! (for CMS HTML content) - Fragment endpoints return text/sexp, auto-wrapped in SexpExpr - All _*_html() helpers converted to _*_sexp() returning sexp source - Head auto-hoist: sexp.js moves meta/title/link/script[ld+json] from rendered body to document.head automatically - Unknown components render warning box instead of crashing page - Component kwargs preserve AST for lazy rendering (fixes <> in kwargs) - Fix unterminated paren in events/sexp/tickets.sexpr Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ from .services import (
|
||||
|
||||
from shared.browser.app.redis_cacher import cache_page
|
||||
from shared.browser.app.utils.htmx import is_htmx_request
|
||||
from shared.sexp.helpers import sexp_response
|
||||
|
||||
def register():
|
||||
browse_bp = Blueprint("browse", __name__)
|
||||
@@ -49,10 +50,10 @@ def register():
|
||||
ctx.update(p_data)
|
||||
if not is_htmx_request():
|
||||
html = await render_market_home_page(ctx)
|
||||
return await make_response(html)
|
||||
else:
|
||||
html = await render_market_home_oob(ctx)
|
||||
|
||||
return await make_response(html)
|
||||
sexp_src = await render_market_home_oob(ctx)
|
||||
return sexp_response(sexp_src)
|
||||
|
||||
@browse_bp.get("/all/")
|
||||
@cache_page(tag="browse")
|
||||
@@ -80,13 +81,15 @@ def register():
|
||||
tctx.update(full_context)
|
||||
if not is_htmx_request():
|
||||
html = await render_browse_page(tctx)
|
||||
resp = await make_response(html)
|
||||
elif product_info["page"] > 1:
|
||||
tctx.update(product_info)
|
||||
html = await render_browse_cards(tctx)
|
||||
sexp_src = await render_browse_cards(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
else:
|
||||
html = await render_browse_oob(tctx)
|
||||
sexp_src = await render_browse_oob(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
|
||||
resp = await make_response(html)
|
||||
resp.headers["Hx-Push-Url"] = _current_url_without_page()
|
||||
return _vary(resp)
|
||||
|
||||
@@ -119,13 +122,15 @@ def register():
|
||||
tctx.update(full_context)
|
||||
if not is_htmx_request():
|
||||
html = await render_browse_page(tctx)
|
||||
resp = await make_response(html)
|
||||
elif product_info["page"] > 1:
|
||||
tctx.update(product_info)
|
||||
html = await render_browse_cards(tctx)
|
||||
sexp_src = await render_browse_cards(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
else:
|
||||
html = await render_browse_oob(tctx)
|
||||
sexp_src = await render_browse_oob(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
|
||||
resp = await make_response(html)
|
||||
resp.headers["Hx-Push-Url"] = _current_url_without_page()
|
||||
return _vary(resp)
|
||||
|
||||
@@ -158,16 +163,18 @@ def register():
|
||||
tctx.update(full_context)
|
||||
if not is_htmx_request():
|
||||
html = await render_browse_page(tctx)
|
||||
resp = await make_response(html)
|
||||
elif product_info["page"] > 1:
|
||||
tctx.update(product_info)
|
||||
html = await render_browse_cards(tctx)
|
||||
sexp_src = await render_browse_cards(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
else:
|
||||
html = await render_browse_oob(tctx)
|
||||
sexp_src = await render_browse_oob(tctx)
|
||||
resp = sexp_response(sexp_src)
|
||||
|
||||
resp = await make_response(html)
|
||||
resp.headers["Hx-Push-Url"] = _current_url_without_page()
|
||||
return _vary(resp)
|
||||
|
||||
|
||||
|
||||
|
||||
return browse_bp
|
||||
@@ -18,7 +18,10 @@ from ...market.filters.qs import decode
|
||||
|
||||
|
||||
def _hx_fragment_request() -> bool:
|
||||
return request.headers.get("HX-Request", "").lower() == "true"
|
||||
return (
|
||||
request.headers.get("SX-Request", "").lower() == "true"
|
||||
or request.headers.get("HX-Request", "").lower() == "true"
|
||||
)
|
||||
|
||||
async def _productInfo(top_slug=None, sub_slug=None):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user