Convert all API endpoint URLs to SX expression format

Every URL at sx-web.org now uses bracketed SX expressions — pages AND
API endpoints. defhandler :path values, sx-get/sx-post/sx-delete attrs,
code examples, and Python route decorators all converted.

- Add SxAtomConverter to handlers.py for parameter matching inside
  expression URLs (e.g. /(api.(item.<sx:item_id>)))
- Convert ~50 defhandler :path values in ref-api.sx and examples.sx
- Convert ~90 sx-get/sx-post/sx-delete URLs in reference.sx, examples.sx
- Convert ~30 code example URLs in examples-content.sx
- Convert ~30 API URLs in pages.py (Python string code examples)
- Convert ~70 page navigation URLs in pages.py
- Convert 7 Python route decorators in routes.py
- Convert ~10 reactive API URLs in marshes.sx
- Add API redirect patterns to sx_router.py (301 for old paths)
- Remove /api/ skip in app.py redirects (old API paths now redirect)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 10:02:26 +00:00
parent da1ca6009a
commit feecbb66ba
11 changed files with 358 additions and 299 deletions

View File

@@ -55,7 +55,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-click
:path "/geography/hypermedia/examples/api/click"
:path "/(geography.(hypermedia.(example.(api.click))))"
:method :get
:returns "element"
(&key)
@@ -73,7 +73,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-form
:path "/geography/hypermedia/examples/api/form"
:path "/(geography.(hypermedia.(example.(api.form))))"
:method :post
:csrf false
:returns "element"
@@ -92,7 +92,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-poll
:path "/geography/hypermedia/examples/api/poll"
:path "/(geography.(hypermedia.(example.(api.poll))))"
:method :get
:returns "element"
(&key)
@@ -113,7 +113,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-delete
:path "/geography/hypermedia/examples/api/delete/<item_id>"
:path "/(geography.(hypermedia.(example.(api.(delete.<sx:item_id>)))))"
:method :delete
:csrf false
:returns "element"
@@ -130,7 +130,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-edit-form
:path "/geography/hypermedia/examples/api/edit"
:path "/(geography.(hypermedia.(example.(api.edit))))"
:method :get
:returns "element"
(&key)
@@ -143,7 +143,7 @@
:text (str "(~inline-edit-form :value \"" value "\")")))))
(defhandler ex-edit-save
:path "/geography/hypermedia/examples/api/edit"
:path "/(geography.(hypermedia.(example.(api.edit))))"
:method :post
:csrf false
:returns "element"
@@ -157,7 +157,7 @@
:text (str "(~inline-view :value \"" value "\")")))))
(defhandler ex-edit-cancel
:path "/geography/hypermedia/examples/api/edit/cancel"
:path "/(geography.(hypermedia.(example.(api.edit-cancel))))"
:method :get
:returns "element"
(&key)
@@ -175,7 +175,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-oob
:path "/geography/hypermedia/examples/api/oob"
:path "/(geography.(hypermedia.(example.(api.oob))))"
:method :get
:returns "element"
(&key)
@@ -195,7 +195,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-lazy
:path "/geography/hypermedia/examples/api/lazy"
:path "/(geography.(hypermedia.(example.(api.lazy))))"
:method :get
:returns "element"
(&key)
@@ -213,7 +213,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-scroll
:path "/geography/hypermedia/examples/api/scroll"
:path "/(geography.(hypermedia.(example.(api.scroll))))"
:method :get
:returns "element"
(&key)
@@ -227,7 +227,7 @@
(range start (+ start 5)))
(if (<= (+ pg 1) 6)
(div :id "scroll-sentinel"
:sx-get (str "/geography/hypermedia/examples/api/scroll?page=" (+ pg 1))
:sx-get (str "/(geography.(hypermedia.(example.(api.scroll))))?page=" (+ pg 1))
:sx-trigger "intersect once"
:sx-target "#scroll-items"
:sx-swap "beforeend"
@@ -244,7 +244,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-progress-start
:path "/geography/hypermedia/examples/api/progress/start"
:path "/(geography.(hypermedia.(example.(api.progress-start))))"
:method :post
:csrf false
:returns "element"
@@ -261,7 +261,7 @@
:text (str "(~progress-status :percent 0 :job-id \"" job-id "\")"))))))
(defhandler ex-progress-status
:path "/geography/hypermedia/examples/api/progress/status"
:path "/(geography.(hypermedia.(example.(api.progress-status))))"
:method :get
:returns "element"
(&key)
@@ -282,7 +282,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-search
:path "/geography/hypermedia/examples/api/search"
:path "/(geography.(hypermedia.(example.(api.search))))"
:method :get
:returns "element"
(&key)
@@ -304,7 +304,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-validate
:path "/geography/hypermedia/examples/api/validate"
:path "/(geography.(hypermedia.(example.(api.validate))))"
:method :get
:returns "element"
(&key)
@@ -331,7 +331,7 @@
:text (nth result 1))))))
(defhandler ex-validate-submit
:path "/geography/hypermedia/examples/api/validate/submit"
:path "/(geography.(hypermedia.(example.(api.validate-submit))))"
:method :post
:csrf false
:returns "element"
@@ -347,7 +347,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-values
:path "/geography/hypermedia/examples/api/values"
:path "/(geography.(hypermedia.(example.(api.values))))"
:method :get
:returns "element"
(&key)
@@ -367,7 +367,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-reset-submit
:path "/geography/hypermedia/examples/api/reset-submit"
:path "/(geography.(hypermedia.(example.(api.reset-submit))))"
:method :post
:csrf false
:returns "element"
@@ -387,7 +387,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-editrow-form
:path "/geography/hypermedia/examples/api/editrow/<row_id>"
:path "/(geography.(hypermedia.(example.(api.(editrow.<sx:row_id>)))))"
:method :get
:returns "element"
(&key row-id)
@@ -402,7 +402,7 @@
:text (str "(~edit-row-form :id \"" (get row "id") "\" ...)"))))))
(defhandler ex-editrow-save
:path "/geography/hypermedia/examples/api/editrow/<row_id>"
:path "/(geography.(hypermedia.(example.(api.(editrow.<sx:row_id>)))))"
:method :post
:csrf false
:returns "element"
@@ -420,7 +420,7 @@
:text (str "(~edit-row-view :id \"" row-id "\" ...)")))))
(defhandler ex-editrow-cancel
:path "/geography/hypermedia/examples/api/editrow/<row_id>/cancel"
:path "/(geography.(hypermedia.(example.(api.(editrow-cancel.<sx:row_id>)))))"
:method :get
:returns "element"
(&key row-id)
@@ -439,7 +439,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-bulk
:path "/geography/hypermedia/examples/api/bulk"
:path "/(geography.(hypermedia.(example.(api.bulk))))"
:method :post
:csrf false
:returns "element"
@@ -476,7 +476,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-swap-log
:path "/geography/hypermedia/examples/api/swap-log"
:path "/(geography.(hypermedia.(example.(api.swap-log))))"
:method :post
:csrf false
:returns "element"
@@ -500,7 +500,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-dashboard
:path "/geography/hypermedia/examples/api/dashboard"
:path "/(geography.(hypermedia.(example.(api.dashboard))))"
:method :get
:returns "element"
(&key)
@@ -530,7 +530,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-tabs
:path "/geography/hypermedia/examples/api/tabs/<tab>"
:path "/(geography.(hypermedia.(example.(api.(tabs.<sx:tab>)))))"
:method :get
:returns "element"
(&key tab)
@@ -551,7 +551,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-animate
:path "/geography/hypermedia/examples/api/animate"
:path "/(geography.(hypermedia.(example.(api.animate))))"
:method :get
:returns "element"
(&key)
@@ -571,7 +571,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-dialog
:path "/geography/hypermedia/examples/api/dialog"
:path "/(geography.(hypermedia.(example.(api.dialog))))"
:method :get
:returns "element"
(&key)
@@ -584,7 +584,7 @@
:text "(~dialog-modal :title \"Confirm Action\" :message \"...\")")))
(defhandler ex-dialog-close
:path "/geography/hypermedia/examples/api/dialog/close"
:path "/(geography.(hypermedia.(example.(api.dialog-close))))"
:method :get
:returns "element"
(&key)
@@ -598,7 +598,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-keyboard
:path "/geography/hypermedia/examples/api/keyboard"
:path "/(geography.(hypermedia.(example.(api.keyboard))))"
:method :get
:returns "element"
(&key)
@@ -617,7 +617,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-pp-edit-all
:path "/geography/hypermedia/examples/api/putpatch/edit-all"
:path "/(geography.(hypermedia.(example.(api.putpatch-edit-all))))"
:method :get
:returns "element"
(&key)
@@ -631,7 +631,7 @@
:text (str "(~pp-form-full :name \"" (get p "name") "\" ...)")))))
(defhandler ex-pp-put
:path "/geography/hypermedia/examples/api/putpatch"
:path "/(geography.(hypermedia.(example.(api.putpatch))))"
:method :put
:csrf false
:returns "element"
@@ -648,7 +648,7 @@
:text (str "(~pp-view :name \"" name "\" ...)")))))
(defhandler ex-pp-cancel
:path "/geography/hypermedia/examples/api/putpatch/cancel"
:path "/(geography.(hypermedia.(example.(api.putpatch-cancel))))"
:method :get
:returns "element"
(&key)
@@ -667,7 +667,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-json-echo
:path "/geography/hypermedia/examples/api/json-echo"
:path "/(geography.(hypermedia.(example.(api.json-echo))))"
:method :post
:csrf false
:returns "element"
@@ -688,7 +688,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-echo-vals
:path "/geography/hypermedia/examples/api/echo-vals"
:path "/(geography.(hypermedia.(example.(api.echo-vals))))"
:method :get
:returns "element"
(&key)
@@ -705,7 +705,7 @@
:text (str "(~echo-result :label \"values\" :items (list ...))")))))))
(defhandler ex-echo-headers
:path "/geography/hypermedia/examples/api/echo-headers"
:path "/(geography.(hypermedia.(example.(api.echo-headers))))"
:method :get
:returns "element"
(&key)
@@ -725,7 +725,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-slow
:path "/geography/hypermedia/examples/api/slow"
:path "/(geography.(hypermedia.(example.(api.slow))))"
:method :get
:returns "element"
(&key)
@@ -744,7 +744,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-slow-search
:path "/geography/hypermedia/examples/api/slow-search"
:path "/(geography.(hypermedia.(example.(api.slow-search))))"
:method :get
:returns "element"
(&key)
@@ -764,7 +764,7 @@
;; --------------------------------------------------------------------------
(defhandler ex-flaky
:path "/geography/hypermedia/examples/api/flaky"
:path "/(geography.(hypermedia.(example.(api.flaky))))"
:method :get
:returns "element"
(&key)

View File

@@ -6,7 +6,7 @@
;; --- sx-get demo: server time ---
(defhandler ref-time
:path "/geography/hypermedia/reference/api/time"
:path "/(geography.(hypermedia.(reference.(api.time))))"
:method :get
:returns "element"
(&key)
@@ -19,7 +19,7 @@
;; --- sx-post demo: greet ---
(defhandler ref-greet
:path "/geography/hypermedia/reference/api/greet"
:path "/(geography.(hypermedia.(reference.(api.greet))))"
:method :post
:csrf false
:returns "element"
@@ -33,7 +33,7 @@
;; --- sx-put demo: status update ---
(defhandler ref-status
:path "/geography/hypermedia/reference/api/status"
:path "/(geography.(hypermedia.(reference.(api.status))))"
:method :put
:csrf false
:returns "element"
@@ -47,7 +47,7 @@
;; --- sx-patch demo: theme ---
(defhandler ref-theme
:path "/geography/hypermedia/reference/api/theme"
:path "/(geography.(hypermedia.(reference.(api.theme))))"
:method :patch
:csrf false
:returns "element"
@@ -61,7 +61,7 @@
;; --- sx-delete demo ---
(defhandler ref-delete-item
:path "/geography/hypermedia/reference/api/item/<item_id>"
:path "/(geography.(hypermedia.(reference.(api.(item.<sx:item_id>)))))"
:method :delete
:csrf false
:returns "element"
@@ -72,7 +72,7 @@
;; --- sx-trigger demo: search ---
(defhandler ref-trigger-search
:path "/geography/hypermedia/reference/api/trigger-search"
:path "/(geography.(hypermedia.(reference.(api.trigger-search))))"
:method :get
:returns "element"
(&key)
@@ -89,7 +89,7 @@
;; --- sx-swap demo ---
(defhandler ref-swap-item
:path "/geography/hypermedia/reference/api/swap-item"
:path "/(geography.(hypermedia.(reference.(api.swap-item))))"
:method :get
:returns "element"
(&key)
@@ -102,7 +102,7 @@
;; --- sx-swap-oob demo ---
(defhandler ref-oob
:path "/geography/hypermedia/reference/api/oob"
:path "/(geography.(hypermedia.(reference.(api.oob))))"
:method :get
:returns "element"
(&key)
@@ -117,7 +117,7 @@
;; --- sx-select demo ---
(defhandler ref-select-page
:path "/geography/hypermedia/reference/api/select-page"
:path "/(geography.(hypermedia.(reference.(api.select-page))))"
:method :get
:returns "element"
(&key)
@@ -134,7 +134,7 @@
;; --- sx-sync demo: slow echo ---
(defhandler ref-slow-echo
:path "/geography/hypermedia/reference/api/slow-echo"
:path "/(geography.(hypermedia.(reference.(api.slow-echo))))"
:method :get
:returns "element"
(&key)
@@ -148,7 +148,7 @@
;; --- sx-prompt demo ---
(defhandler ref-prompt-echo
:path "/geography/hypermedia/reference/api/prompt-echo"
:path "/(geography.(hypermedia.(reference.(api.prompt-echo))))"
:method :get
:returns "element"
(&key)
@@ -161,7 +161,7 @@
;; --- Error demo ---
(defhandler ref-error-500
:path "/geography/hypermedia/reference/api/error-500"
:path "/(geography.(hypermedia.(reference.(api.error-500))))"
:method :get
:returns "nil"
(&key)
@@ -175,7 +175,7 @@
;; --- sx-encoding demo: file upload name ---
(defhandler ref-upload-name
:path "/geography/hypermedia/reference/api/upload-name"
:path "/(geography.(hypermedia.(reference.(api.upload-name))))"
:method :post
:csrf false
:returns "element"
@@ -190,7 +190,7 @@
;; --- sx-headers demo: echo custom headers ---
(defhandler ref-echo-headers
:path "/geography/hypermedia/reference/api/echo-headers"
:path "/(geography.(hypermedia.(reference.(api.echo-headers))))"
:method :get
:returns "element"
(&key)
@@ -214,7 +214,7 @@
;; --- sx-include demo: echo GET query params ---
(defhandler ref-echo-vals-get
:path "/geography/hypermedia/reference/api/echo-vals"
:path "/(geography.(hypermedia.(reference.(api.echo-vals))))"
:method :get
:returns "element"
(&key)
@@ -235,7 +235,7 @@
;; --- sx-vals demo: echo POST form values ---
(defhandler ref-echo-vals-post
:path "/geography/hypermedia/reference/api/echo-vals"
:path "/(geography.(hypermedia.(reference.(api.echo-vals))))"
:method :post
:csrf false
:returns "element"
@@ -257,7 +257,7 @@
;; --- sx-retry demo: flaky endpoint (fails 2/3 times) ---
(defhandler ref-flaky
:path "/geography/hypermedia/reference/api/flaky"
:path "/(geography.(hypermedia.(reference.(api.flaky))))"
:method :get
:returns "element"
(&key)
@@ -275,7 +275,7 @@
;; --- sx-trigger-event demo: response header triggers ---
(defhandler ref-trigger-event
:path "/geography/hypermedia/reference/api/trigger-event"
:path "/(geography.(hypermedia.(reference.(api.trigger-event))))"
:method :get
:returns "element"
(&key)
@@ -287,7 +287,7 @@
;; --- sx-retarget demo: response header retargets ---
(defhandler ref-retarget
:path "/geography/hypermedia/reference/api/retarget"
:path "/(geography.(hypermedia.(reference.(api.retarget))))"
:method :get
:returns "element"
(&key)