Externalize sexp component templates and delete redundant HTML fragments
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m13s

Move 24 defcomp definitions from Python string constants in components.py
to 7 grouped .sexp files under shared/sexp/templates/. Add load_sexp_dir()
to jinja_bridge.py for file-based loading. Migrate events and market
link-card fragment handlers from render_template to sexp. Delete 9
superseded Jinja HTML fragment templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 08:55:54 +00:00
parent 9c6170ed31
commit 53c4a0a1e0
20 changed files with 506 additions and 1029 deletions

View File

@@ -176,6 +176,7 @@ def register():
async def _link_card_handler():
from shared.infrastructure.urls import events_url
from shared.sexp.jinja_bridge import sexp as render_sexp
slug = request.args.get("slug", "")
keys_raw = request.args.get("keys", "")
@@ -193,12 +194,10 @@ def register():
g.s, "page", post.id,
)
cal_names = ", ".join(c.name for c in calendars) if calendars else ""
parts.append(await render_template(
"fragments/link_card.html",
title=post.title,
feature_image=post.feature_image,
calendar_names=cal_names,
link=events_url(f"/{post.slug}"),
parts.append(render_sexp(
'(~link-card :title title :image image :subtitle subtitle :link link)',
title=post.title, image=post.feature_image,
subtitle=cal_names, link=events_url(f"/{post.slug}"),
))
return "\n".join(parts)
@@ -213,12 +212,10 @@ def register():
g.s, "page", post.id,
)
cal_names = ", ".join(c.name for c in calendars) if calendars else ""
return await render_template(
"fragments/link_card.html",
title=post.title,
feature_image=post.feature_image,
calendar_names=cal_names,
link=events_url(f"/{post.slug}"),
return render_sexp(
'(~link-card :title title :image image :subtitle subtitle :link link)',
title=post.title, image=post.feature_image,
subtitle=cal_names, link=events_url(f"/{post.slug}"),
)
_handlers["link-card"] = _link_card_handler

View File

@@ -1,10 +0,0 @@
{# Calendar links nav — served as fragment from events app #}
{% for calendar in calendars %}
{% set local_href=events_url('/' + post_slug + '/calendars/' + calendar.slug + '/') %}
<a
href="{{ local_href }}"
class="{{styles.nav_button_less_pad}}">
<i class="fa fa-calendar" aria-hidden="true"></i>
<div>{{calendar.name}}</div>
</a>
{% endfor %}

View File

@@ -1,28 +0,0 @@
{# Calendar entries nav — served as fragment from events app #}
{% for entry in entries %}
{% set _entry_path = '/' + post_slug + '/calendars/' + entry.calendar_slug + '/' + entry.start_at.year|string + '/' + entry.start_at.month|string + '/' + entry.start_at.day|string + '/entries/' + entry.id|string + '/' %}
<a
href="{{ events_url(_entry_path) }}"
class="{{styles.nav_button_less_pad}}"
>
<div class="w-8 h-8 rounded bg-stone-200 flex-shrink-0"></div>
<div class="flex-1 min-w-0">
<div class="font-medium truncate">{{ entry.name }}</div>
<div class="text-xs text-stone-600 truncate">
{{ entry.start_at.strftime('%b %d, %Y at %H:%M') }}
{% if entry.end_at %} {{ entry.end_at.strftime('%H:%M') }}{% endif %}
</div>
</div>
</a>
{% endfor %}
{# Infinite scroll sentinel — URL points back to the consumer app #}
{% if has_more and paginate_url_base %}
<div id="entries-load-sentinel-{{ page }}"
hx-get="{{ paginate_url_base }}?page={{ page + 1 }}"
hx-trigger="intersect once"
hx-swap="beforebegin"
_="on htmx:afterRequest trigger scroll on #associated-entries-container"
class="flex-shrink-0 w-1">
</div>
{% endif %}

View File

@@ -1,17 +0,0 @@
<a href="{{ link }}" class="block rounded border border-stone-200 bg-white hover:bg-stone-50 transition-colors no-underline" data-fragment="link-card" data-app="events" data-hx-disable>
<div class="flex flex-row items-start gap-3 p-3">
{% if feature_image %}
<img src="{{ feature_image }}" alt="" class="flex-shrink-0 w-16 h-16 rounded object-cover">
{% else %}
<div class="flex-shrink-0 w-16 h-16 rounded bg-stone-100 flex items-center justify-center text-stone-400">
<i class="fas fa-calendar text-lg"></i>
</div>
{% endif %}
<div class="flex-1 min-w-0">
<div class="font-medium text-stone-900 text-sm clamp-2">{{ title }}</div>
{% if calendar_names %}
<div class="text-xs text-stone-500 mt-0.5">{{ calendar_names }}</div>
{% endif %}
</div>
</div>
</a>