Replace JSON sx-headers with SX dict expressions, fix blog like component
sx-headers attributes now use native SX dict format {:key val} instead of
JSON strings. Eliminates manual JSON string construction in both .sx files
and Python callers.
- sx.js: parse sx-headers/sx-vals as SX dict ({: prefix) with JSON fallback,
add _serializeDict for dict→attribute serialization, fix verbInfo scope in
_doFetch error handler
- html.py: serialize dict attribute values via SX serialize() not str()
- All .sx files: {:X-CSRFToken csrf} replaces (str "{\"X-CSRFToken\": ...}")
- All Python callers: {"X-CSRFToken": csrf} dict replaces f-string JSON
- Blog like: extract ~blog-like-toggle, fix POST returning wrong component,
fix emoji escapes in .sx (parser has no \U support), fix card :hx-headers
keyword mismatch, wrap sx_content in SxExpr for evaluation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -323,7 +323,7 @@ def _calendars_list_sx(ctx: dict, calendars: list) -> str:
|
||||
cal_name = getattr(cal, "name", "")
|
||||
href = prefix + url_for("calendar.get", calendar_slug=cal_slug)
|
||||
del_url = url_for("calendar.delete", calendar_slug=cal_slug)
|
||||
csrf_hdr = f'{{"X-CSRFToken":"{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
parts.append(sx_call("crud-item",
|
||||
href=href, name=cal_name, slug=cal_slug,
|
||||
del_url=del_url, csrf_hdr=csrf_hdr,
|
||||
@@ -656,7 +656,7 @@ def _markets_list_html(ctx: dict, markets: list) -> str:
|
||||
m_name = getattr(m, "name", "") if hasattr(m, "name") else m.get("name", "")
|
||||
market_href = call_url(ctx, "market_url", f"/{slug}/{m_slug}/")
|
||||
del_url = url_for("markets.delete_market", market_slug=m_slug)
|
||||
csrf_hdr = f'{{"X-CSRFToken":"{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
parts.append(sx_call("crud-item",
|
||||
href=market_href, name=m_name,
|
||||
slug=m_slug, del_url=del_url,
|
||||
|
||||
@@ -552,7 +552,7 @@ def render_entry_posts_panel(entry_posts, entry, calendar, day, month, year) ->
|
||||
items += sx_call("events-entry-post-item",
|
||||
img=img_html, title=ep_title,
|
||||
del_url=del_url, entry_id=eid_s,
|
||||
csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}')
|
||||
csrf_hdr={"X-CSRFToken": csrf})
|
||||
posts_html = sx_call("events-entry-posts-list", items=SxExpr(items))
|
||||
else:
|
||||
posts_html = sx_call("events-entry-posts-none")
|
||||
|
||||
@@ -387,7 +387,7 @@ async def _h_slots_data(calendar_slug=None, **kw) -> dict:
|
||||
csrf = generate_csrf_token()
|
||||
cal_slug = getattr(calendar, "slug", "")
|
||||
hx_select = getattr(g, "hx_select_search", "#main-panel")
|
||||
csrf_hdr = f'{{"X-CSRFToken": "{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
add_url = url_for("calendar.slots.add_form", calendar_slug=cal_slug)
|
||||
|
||||
slots_list = []
|
||||
@@ -624,7 +624,7 @@ async def _h_ticket_types_data(calendar_slug=None, entry_id=None,
|
||||
cal_slug = getattr(calendar, "slug", "")
|
||||
hx_select = getattr(g, "hx_select_search", "#main-panel")
|
||||
eid = entry.id if entry else 0
|
||||
csrf_hdr = f'{{"X-CSRFToken": "{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
|
||||
types_list = []
|
||||
for tt in (ticket_types or []):
|
||||
@@ -964,7 +964,7 @@ async def _h_markets_data(**kw) -> dict:
|
||||
|
||||
post = ctx.get("post") or {}
|
||||
slug = post.get("slug", "")
|
||||
csrf_hdr = f'{{"X-CSRFToken":"{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
|
||||
markets_list = []
|
||||
for m in markets_raw:
|
||||
|
||||
@@ -263,7 +263,7 @@ def render_slots_table(slots, calendar) -> str:
|
||||
time_str=f"{time_start} - {time_end}",
|
||||
cost_str=cost_str, action_btn=action_btn,
|
||||
del_url=del_url,
|
||||
csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}')
|
||||
csrf_hdr={"X-CSRFToken": csrf})
|
||||
else:
|
||||
rows_html = sx_call("events-slots-empty-row")
|
||||
|
||||
@@ -343,7 +343,7 @@ def render_slot_add_form(calendar) -> str:
|
||||
|
||||
post_url = url_for("calendar.slots.post", calendar_slug=cal_slug)
|
||||
cancel_url = url_for("calendar.slots.add_button", calendar_slug=cal_slug)
|
||||
csrf_hdr = f'{{"X-CSRFToken": "{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
|
||||
# Days checkboxes (all unchecked for add)
|
||||
day_keys = [("mon", "Mon"), ("tue", "Tue"), ("wed", "Wed"), ("thu", "Thu"),
|
||||
|
||||
@@ -419,7 +419,7 @@ def render_ticket_types_table(ticket_types, entry, calendar, day, month, year) -
|
||||
tt_name=tt.name, cost_str=cost_str,
|
||||
count=str(tt.count), action_btn=action_btn,
|
||||
del_url=del_url,
|
||||
csrf_hdr=f'{{"X-CSRFToken": "{csrf}"}}')
|
||||
csrf_hdr={"X-CSRFToken": csrf})
|
||||
else:
|
||||
rows_html = sx_call("events-ticket-types-empty-row")
|
||||
|
||||
@@ -699,7 +699,7 @@ def render_ticket_type_add_form(entry, calendar, day, month, year) -> str:
|
||||
cancel_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.add_button",
|
||||
calendar_slug=cal_slug, entry_id=entry.id,
|
||||
year=year, month=month, day=day)
|
||||
csrf_hdr = f'{{"X-CSRFToken": "{csrf}"}}'
|
||||
csrf_hdr = {"X-CSRFToken": csrf}
|
||||
|
||||
return sx_call("events-ticket-type-add-form",
|
||||
post_url=post_url, csrf=csrf_hdr,
|
||||
|
||||
Reference in New Issue
Block a user