Remove render_to_sx from public API: enforce sx_call for all service code
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m44s

Replace ~250 render_to_sx calls across all services with sync sx_call,
converting many async functions to sync where no other awaits remained.
Make render_to_sx/render_to_sx_with_env private (_render_to_sx).
Add (post-header-ctx) IO primitive and shared post/post-admin defmacros.
Convert built-in post/post-admin layouts from Python to register_sx_layout
with .sx defcomps. Remove dead post_admin_mobile_nav_sx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 19:30:45 +00:00
parent 57e0d0c341
commit 959e63d440
61 changed files with 1352 additions and 1208 deletions

View File

@@ -106,7 +106,7 @@ def register():
async def post_detail(slug: str):
from shared.sx.page import get_template_context
from shared.sx.helpers import (
render_to_sx, root_header_sx, full_page_sx, oob_page_sx,
sx_call, root_header_sx, full_page_sx, oob_page_sx,
post_header_sx, oob_header_sx, mobile_menu_sx,
post_mobile_nav_sx, mobile_root_nav_sx,
)
@@ -124,9 +124,9 @@ def register():
csrf = generate_csrf_token()
svc = services.blog_page
detail_data = svc.post_detail_data(post, user, rights, csrf, blog_url_base)
content = await render_to_sx("blog-post-detail-content", **detail_data)
content = sx_call("blog-post-detail-content", **detail_data)
meta_data = svc.post_meta_data(post, tctx.get("base_title", ""))
meta = await render_to_sx("blog-meta", **meta_data)
meta = sx_call("blog-meta", **meta_data)
if not is_htmx_request():
root_hdr = await root_header_sx(tctx)
@@ -149,24 +149,24 @@ def register():
@clear_cache(tag="post.post_detail", tag_scope="user")
async def like_toggle(slug: str):
from shared.utils import host_url
from shared.sx.helpers import render_to_sx
from shared.sx.helpers import sx_call
from shared.browser.app.csrf import generate_csrf_token
like_url = host_url(url_for('blog.post.like_toggle', slug=slug))
csrf = generate_csrf_token()
async def _like_btn(liked):
def _like_btn(liked):
if liked:
colour, icon, label = "text-red-600", "fa-solid fa-heart", "Unlike this post"
else:
colour, icon, label = "text-stone-300", "fa-regular fa-heart", "Like this post"
return await render_to_sx("market-like-toggle-button",
return sx_call("market-like-toggle-button",
colour=colour, action=like_url,
hx_headers=f'{{"X-CSRFToken": "{csrf}"}}',
label=label, icon_cls=icon)
if not g.user:
return sx_response(await _like_btn(False), status=403)
return sx_response(_like_btn(False), status=403)
post_id = g.post_data["post"]["id"]
user_id = g.user.id
@@ -175,7 +175,7 @@ def register():
"user_id": user_id, "target_type": "post", "target_id": post_id,
})
return sx_response(await _like_btn(result["liked"]))
return sx_response(_like_btn(result["liked"]))
@bp.get("/w/<widget_domain>/")
async def widget_paginate(slug: str, widget_domain: str):