Move home/post detail/like rendering from Python to .sx defcomps
- Home page: inline shared helpers, render_to_sx("blog-home-main")
- Post detail: new ~blog-post-detail-content defcomp with data from service
- Like toggle: call render_to_sx("market-like-toggle-button") directly
- Add post_meta_data() and post_detail_data() to BlogPageService
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -118,15 +118,38 @@ def register(url_prefix, title):
|
||||
ctx["page_cart_total"] = float(page_summary.total + page_summary.calendar_total + page_summary.ticket_total)
|
||||
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_home_page, render_home_oob
|
||||
from shared.sx.helpers import (
|
||||
render_to_sx, 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,
|
||||
)
|
||||
from shared.sx.parser import SxExpr
|
||||
from shared.services.registry import services
|
||||
|
||||
tctx = await get_template_context()
|
||||
tctx.update(ctx)
|
||||
|
||||
post = ctx.get("post", {})
|
||||
content = await render_to_sx("blog-home-main",
|
||||
html_content=post.get("html", ""),
|
||||
sx_content=SxExpr(post.get("sx_content", "")) if post.get("sx_content") else None)
|
||||
meta_data = services.get("blog_page").post_meta_data(post, ctx.get("base_title", ""))
|
||||
meta = await render_to_sx("blog-meta", **meta_data)
|
||||
|
||||
if not is_htmx_request():
|
||||
html = await render_home_page(tctx)
|
||||
root_hdr = await root_header_sx(tctx)
|
||||
post_hdr = await post_header_sx(tctx)
|
||||
header_rows = "(<> " + root_hdr + " " + post_hdr + ")"
|
||||
menu = mobile_menu_sx(await post_mobile_nav_sx(tctx), await mobile_root_nav_sx(tctx))
|
||||
html = await full_page_sx(tctx, header_rows=header_rows, content=content,
|
||||
meta=meta, menu=menu)
|
||||
return await make_response(html)
|
||||
else:
|
||||
sx_src = await render_home_oob(tctx)
|
||||
root_hdr = await root_header_sx(tctx)
|
||||
post_hdr = await post_header_sx(tctx)
|
||||
rows = "(<> " + root_hdr + " " + post_hdr + ")"
|
||||
header_oob = await oob_header_sx("root-header-child", "post-header-child", rows)
|
||||
sx_src = await oob_page_sx(oobs=header_oob, content=content)
|
||||
return sx_response(sx_src)
|
||||
|
||||
@blogs_bp.get("/index")
|
||||
|
||||
@@ -105,27 +105,68 @@ def register():
|
||||
@cache_page(tag="post.post_detail")
|
||||
async def post_detail(slug: str):
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_post_page, render_post_oob
|
||||
from shared.sx.helpers import (
|
||||
render_to_sx, 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,
|
||||
)
|
||||
from shared.services.registry import services
|
||||
from shared.browser.app.csrf import generate_csrf_token
|
||||
from shared.utils import host_url
|
||||
|
||||
tctx = await get_template_context()
|
||||
|
||||
# Render post content via .sx defcomp
|
||||
post = tctx.get("post") or {}
|
||||
user = getattr(g, "user", None)
|
||||
rights = tctx.get("rights") or {}
|
||||
blog_url_base = host_url(url_for("blog.index")).rstrip("/index").rstrip("/")
|
||||
csrf = generate_csrf_token()
|
||||
svc = services.get("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)
|
||||
meta_data = svc.post_meta_data(post, tctx.get("base_title", ""))
|
||||
meta = await render_to_sx("blog-meta", **meta_data)
|
||||
|
||||
if not is_htmx_request():
|
||||
html = await render_post_page(tctx)
|
||||
root_hdr = await root_header_sx(tctx)
|
||||
post_hdr = await post_header_sx(tctx)
|
||||
header_rows = "(<> " + root_hdr + " " + post_hdr + ")"
|
||||
menu = mobile_menu_sx(await post_mobile_nav_sx(tctx), await mobile_root_nav_sx(tctx))
|
||||
html = await full_page_sx(tctx, header_rows=header_rows, content=content,
|
||||
meta=meta, menu=menu)
|
||||
return await make_response(html)
|
||||
else:
|
||||
sx_src = await render_post_oob(tctx)
|
||||
root_hdr = await root_header_sx(tctx)
|
||||
post_hdr = await post_header_sx(tctx)
|
||||
rows = "(<> " + root_hdr + " " + post_hdr + ")"
|
||||
header_oob = await oob_header_sx("root-header-child", "post-header-child", rows)
|
||||
sx_src = await oob_page_sx(oobs=header_oob, content=content, menu=
|
||||
mobile_menu_sx(await post_mobile_nav_sx(tctx), await mobile_root_nav_sx(tctx)))
|
||||
return sx_response(sx_src)
|
||||
|
||||
@bp.post("/like/toggle/")
|
||||
@clear_cache(tag="post.post_detail", tag_scope="user")
|
||||
async def like_toggle(slug: str):
|
||||
from shared.utils import host_url
|
||||
from sx.sx_components import render_like_toggle_button
|
||||
from shared.sx.helpers import render_to_sx
|
||||
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):
|
||||
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",
|
||||
colour=colour, action=like_url,
|
||||
hx_headers=f'{{"X-CSRFToken": "{csrf}"}}',
|
||||
label=label, icon_cls=icon)
|
||||
|
||||
# Get post_id from g.post_data
|
||||
if not g.user:
|
||||
return sx_response(await render_like_toggle_button(slug, False, like_url), status=403)
|
||||
return sx_response(await _like_btn(False), status=403)
|
||||
|
||||
post_id = g.post_data["post"]["id"]
|
||||
user_id = g.user.id
|
||||
@@ -133,9 +174,8 @@ def register():
|
||||
result = await call_action("likes", "toggle", payload={
|
||||
"user_id": user_id, "target_type": "post", "target_id": post_id,
|
||||
})
|
||||
liked = result["liked"]
|
||||
|
||||
return sx_response(await render_like_toggle_button(slug, liked, like_url))
|
||||
return sx_response(await _like_btn(result["liked"]))
|
||||
|
||||
@bp.get("/w/<widget_domain>/")
|
||||
async def widget_paginate(slug: str, widget_domain: str):
|
||||
|
||||
Reference in New Issue
Block a user