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:
@@ -206,7 +206,7 @@
|
||||
(when is-admin
|
||||
(~blog-snippet-visibility-select
|
||||
:patch-url (get s "patch_url")
|
||||
:hx-headers (str "{\"X-CSRFToken\": \"" csrf "\"}")
|
||||
:hx-headers {:X-CSRFToken csrf}
|
||||
:options (<>
|
||||
(~blog-snippet-option :value "private" :selected (= vis "private") :label "private")
|
||||
(~blog-snippet-option :value "shared" :selected (= vis "shared") :label "shared")
|
||||
@@ -217,7 +217,7 @@
|
||||
:trigger-target "#snippets-list"
|
||||
:title "Delete snippet?"
|
||||
:text (str "Delete \u201c" name "\u201d?")
|
||||
:sx-headers (str "{\"X-CSRFToken\": \"" csrf "\"}")
|
||||
:sx-headers {:X-CSRFToken csrf}
|
||||
:cls "px-3 py-1 text-sm bg-red-200 hover:bg-red-300 rounded text-red-800 flex-shrink-0"))))))
|
||||
(or snippets (list)))))))
|
||||
|
||||
@@ -240,7 +240,7 @@
|
||||
:edit-url (get mi "edit_url")
|
||||
:delete-url (get mi "delete_url")
|
||||
:confirm-text (str "Remove " (get mi "label") " from the menu?")
|
||||
:hx-headers (str "{\"X-CSRFToken\": \"" csrf "\"}")))
|
||||
:hx-headers {:X-CSRFToken csrf}))
|
||||
(or menu-items (list)))))))
|
||||
|
||||
;; Tag Groups — receives serialized tag group data from service
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
(defcomp ~blog-like-button (&key like-url hx-headers heart)
|
||||
(div :class "absolute top-20 right-2 z-10 text-6xl md:text-4xl"
|
||||
(button :sx-post like-url :sx-swap "outerHTML"
|
||||
:sx-headers hx-headers :class "cursor-pointer" heart)))
|
||||
(~blog-like-toggle :like-url like-url :hx-headers hx-headers :heart heart)))
|
||||
|
||||
(defcomp ~blog-draft-status (&key publish-requested timestamp)
|
||||
(<> (div :class "flex justify-center gap-2 mt-1"
|
||||
@@ -56,7 +55,7 @@
|
||||
(when has-like
|
||||
(~blog-like-button
|
||||
:like-url like-url
|
||||
:sx-headers (str "{\"X-CSRFToken\": \"" csrf-token "\"}")
|
||||
:hx-headers {:X-CSRFToken csrf-token}
|
||||
:heart (if liked "❤️" "🤍")))
|
||||
(a :href href :sx-get href :sx-target "#main-panel"
|
||||
:sx-select (or hx-select "#main-panel") :sx-swap "outerHTML" :sx-push-url "true"
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
(when publish-requested (span :class "inline-block px-3 py-1 rounded-full text-sm font-semibold bg-blue-100 text-blue-800" "Publish requested"))
|
||||
edit))
|
||||
|
||||
(defcomp ~blog-like-toggle (&key like-url hx-headers heart)
|
||||
(button :sx-post like-url :sx-swap "outerHTML"
|
||||
:sx-headers hx-headers :class "cursor-pointer" heart))
|
||||
|
||||
(defcomp ~blog-detail-like (&key like-url hx-headers heart)
|
||||
(div :class "absolute top-2 right-2 z-10 text-8xl md:text-6xl"
|
||||
(button :sx-post like-url :sx-swap "outerHTML"
|
||||
:sx-headers hx-headers :class "cursor-pointer" heart)))
|
||||
(~blog-like-toggle :like-url like-url :hx-headers hx-headers :heart heart)))
|
||||
|
||||
(defcomp ~blog-detail-excerpt (&key excerpt)
|
||||
(div :class "w-full text-center italic text-3xl p-2" excerpt))
|
||||
@@ -55,8 +58,8 @@
|
||||
:like (when has-user
|
||||
(~blog-detail-like
|
||||
:like-url like-url
|
||||
:hx-headers (str "{\"X-CSRFToken\": \"" csrf "\"}")
|
||||
:heart (if liked "\u2764\ufe0f" "\U0001f90d")))
|
||||
:hx-headers {:X-CSRFToken csrf}
|
||||
:heart (if liked "❤️" "🤍")))
|
||||
:excerpt (when (not (= custom-excerpt ""))
|
||||
(~blog-detail-excerpt :excerpt custom-excerpt))
|
||||
:at-bar (~blog-at-bar :tags tags :authors authors)))))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
(defcomp ~blog-features-form (&key features-url calendar-checked market-checked hs-trigger)
|
||||
(form :sx-put features-url :sx-target "#features-panel" :sx-swap "outerHTML"
|
||||
:sx-headers "{\"Content-Type\": \"application/json\"}" :sx-encoding "json" :class "space-y-3"
|
||||
:sx-headers {:Content-Type "application/json"} :sx-encoding "json" :class "space-y-3"
|
||||
(label :class "flex items-center gap-3 cursor-pointer"
|
||||
(input :type "checkbox" :name "calendar" :value "true" :checked calendar-checked
|
||||
:class "h-5 w-5 rounded border-stone-300 text-blue-600 focus:ring-blue-500"
|
||||
@@ -140,7 +140,7 @@
|
||||
(~blog-associated-entry
|
||||
:confirm-text (get e "confirm_text")
|
||||
:toggle-url (get e "toggle_url")
|
||||
:hx-headers (str "{\"X-CSRFToken\": \"" csrf "\"}")
|
||||
:hx-headers {:X-CSRFToken csrf}
|
||||
:img (~blog-entry-image :src (get e "cal_image") :title (get e "cal_title"))
|
||||
:name (get e "name")
|
||||
:date-str (get e "date_str")))
|
||||
|
||||
Reference in New Issue
Block a user