Convert social and federation profile from Jinja to SX rendering
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 14m34s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 14m34s
Add primitives (replace, strip-tags, slice, csrf-token), convert all social blueprint routes and federation profile to SX content builders, delete 12 unused Jinja templates and social_lite layout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,77 @@ def _is_aggregate(app_name: str) -> bool:
|
||||
return app_name == "federation"
|
||||
|
||||
|
||||
async def _render_profile_sx(actor, activities, total):
|
||||
"""Render the federation actor profile page using SX."""
|
||||
from markupsafe import escape
|
||||
from shared.sx.page import get_template_context
|
||||
from shared.sx.helpers import full_page_sx, oob_page_sx, sx_response
|
||||
from shared.browser.app.utils.htmx import is_htmx_request
|
||||
from shared.config import config
|
||||
|
||||
def _e(v):
|
||||
s = str(v) if v else ""
|
||||
return str(escape(s)).replace('"', '\\"')
|
||||
|
||||
username = _e(actor.preferred_username)
|
||||
display_name = _e(actor.display_name or actor.preferred_username)
|
||||
ap_domain = config().get("ap_domain", "rose-ash.com")
|
||||
|
||||
summary_el = ""
|
||||
if actor.summary:
|
||||
summary_el = f'(p :class "mt-2" "{_e(actor.summary)}")'
|
||||
|
||||
activity_items = []
|
||||
for a in activities:
|
||||
ts = ""
|
||||
if a.published:
|
||||
ts = a.published.strftime("%Y-%m-%d %H:%M")
|
||||
obj_el = ""
|
||||
if a.object_type:
|
||||
obj_el = f'(span :class "text-sm text-stone-500" "{_e(a.object_type)}")'
|
||||
activity_items.append(
|
||||
f'(div :class "bg-white rounded-lg shadow p-4"'
|
||||
f' (div :class "flex justify-between items-start"'
|
||||
f' (span :class "font-medium" "{_e(a.activity_type)}")'
|
||||
f' (span :class "text-sm text-stone-400" "{_e(ts)}"))'
|
||||
f' {obj_el})')
|
||||
|
||||
if activities:
|
||||
activities_el = ('(div :class "space-y-4" ' +
|
||||
" ".join(activity_items) + ")")
|
||||
else:
|
||||
activities_el = '(p :class "text-stone-500" "No activities yet.")'
|
||||
|
||||
content = (
|
||||
f'(div :id "main-panel"'
|
||||
f' (div :class "py-8"'
|
||||
f' (div :class "bg-white rounded-lg shadow p-6 mb-6"'
|
||||
f' (h1 :class "text-2xl font-bold" "{display_name}")'
|
||||
f' (p :class "text-stone-500" "@{username}@{_e(ap_domain)}")'
|
||||
f' {summary_el})'
|
||||
f' (h2 :class "text-xl font-bold mb-4" "Activities ({total})")'
|
||||
f' {activities_el}))')
|
||||
|
||||
tctx = await get_template_context()
|
||||
|
||||
if is_htmx_request():
|
||||
# Import federation layout for OOB headers
|
||||
try:
|
||||
from federation.sxc.pages import _social_oob
|
||||
oob_headers = _social_oob(tctx)
|
||||
except ImportError:
|
||||
oob_headers = ""
|
||||
return sx_response(oob_page_sx(oobs=oob_headers, content=content))
|
||||
else:
|
||||
try:
|
||||
from federation.sxc.pages import _social_full
|
||||
header_rows = _social_full(tctx)
|
||||
except ImportError:
|
||||
from shared.sx.helpers import root_header_sx
|
||||
header_rows = root_header_sx(tctx)
|
||||
return full_page_sx(tctx, header_rows=header_rows, content=content)
|
||||
|
||||
|
||||
def create_activitypub_blueprint(app_name: str) -> Blueprint:
|
||||
"""Return a Blueprint with AP endpoints for *app_name*."""
|
||||
bp = Blueprint("activitypub", __name__)
|
||||
@@ -272,16 +343,10 @@ def create_activitypub_blueprint(app_name: str) -> Blueprint:
|
||||
|
||||
# HTML: federation renders its own profile; other apps redirect there
|
||||
if aggregate:
|
||||
from quart import render_template
|
||||
activities, total = await services.federation.get_outbox(
|
||||
g._ap_s, username, page=1, per_page=20,
|
||||
)
|
||||
return await render_template(
|
||||
"federation/profile.html",
|
||||
actor=actor,
|
||||
activities=activities,
|
||||
total=total,
|
||||
)
|
||||
return await _render_profile_sx(actor, activities, total)
|
||||
from quart import redirect
|
||||
return redirect(f"https://{fed_domain}/users/{username}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user