- Add setup_sexp_bridge() and load_shared_components() to factory.py so all services get s-expression support automatically - Create shared/sexp/components.py with ~link-card component definition (replaces 5 per-service Jinja link_card.html templates) - Replace blog's link-card fragment handler to use sexp() instead of render_template() — first real s-expression rendered page content Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
52 lines
2.0 KiB
Python
52 lines
2.0 KiB
Python
"""
|
|
Shared s-expression component definitions.
|
|
|
|
Loaded at app startup via ``load_shared_components()``. Each component
|
|
replaces a per-service Jinja fragment template with a single reusable
|
|
s-expression definition.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .jinja_bridge import register_components
|
|
|
|
|
|
def load_shared_components() -> None:
|
|
"""Register all shared s-expression components."""
|
|
register_components(_LINK_CARD)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ~link-card
|
|
# ---------------------------------------------------------------------------
|
|
# Replaces: blog/templates/fragments/link_card.html
|
|
# market/templates/fragments/link_card.html
|
|
# events/templates/fragments/link_card.html
|
|
# federation/templates/fragments/link_card.html
|
|
# artdag/l1/app/templates/fragments/link_card.html
|
|
#
|
|
# Usage:
|
|
# sexp('(~link-card :link "/post/apple/" :title "Apple" :image "/img/a.jpg")')
|
|
# sexp('(~link-card :link url :title title :icon "fas fa-file-alt")', **ctx)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
_LINK_CARD = '''
|
|
(defcomp ~link-card (&key link title image icon subtitle detail data-app)
|
|
(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 data-app
|
|
:data-hx-disable true
|
|
(div :class "flex flex-row items-start gap-3 p-3"
|
|
(if image
|
|
(img :src image :alt "" :class "flex-shrink-0 w-16 h-16 rounded object-cover")
|
|
(div :class "flex-shrink-0 w-16 h-16 rounded bg-stone-100 flex items-center justify-center text-stone-400"
|
|
(i :class icon)))
|
|
(div :class "flex-1 min-w-0"
|
|
(div :class "font-medium text-stone-900 text-sm clamp-2" title)
|
|
(when subtitle
|
|
(div :class "text-xs text-stone-500 mt-0.5" subtitle))
|
|
(when detail
|
|
(div :class "text-xs text-stone-400 mt-1" detail))))))
|
|
'''
|