Commit9eb9a27bRecorded19 Feb 2026Repositorysigil-web-demo
refactor: Deduplicate sigil-web UI helpers and demo boilerplate
Message
Add optional-attrs utility to eliminate verbose ,@(if x ...) attribute patterns across all components. Add coerce-field-value for automatic number->string conversion in field helpers. Consolidate sg-text-field, sg-email-field, sg-password-field into thin wrappers around sg-input-field. Extract parse-page-param, not-found-page, and parse-optional-int helpers in the demo to remove duplicated logic.
Changed
src/sigil/web/demo.sgl | 31 +++++++++++++++----------------
src/sigil/web/demo/db.sgl | 22 ++++++++++++++--------
src/sigil/web/demo/views.sgl | 12 ++----------
3 files changed, 31 insertions(+), 34 deletions(-)Diff
src/sigil/web/demo.sglmodified
@@ -50,6 +50,17 @@
50
(parse-form-urlencoded (http-request-query req)) 51
'())) 52
+53
(define (parse-page-param params)+54
(or (and (assoc-ref 'page params)+55
(string->number (assoc-ref 'page params)))+56
1))+57
+58
(define (not-found-page)+59
(render-page "Not Found"+60
'(div (h1 "Record Not Found")+61
(p "The record you're looking for doesn't exist.")+62
(a (@ (href "/records")) "Back to collection"))))+63
64
;; Simple validation: returns alist of errors or #f 65
(define (validate-record params) 66
(let ((errors '()))@@ -88,9 +99,7 @@
99
(define (records-handler req) 100
(let* ((db (db-from-req req)) 101
(params (parse-query-params req))−91
(page (or (and (assoc-ref 'page params)−92
(string->number (assoc-ref 'page params)))−93
1))+102
(page (parse-page-param params)) 103
(search (assoc-ref 'q params #f)) 104
(per-page 10) 105
(total (count-records db search))@@ -113,11 +122,7 @@
122
(http-response/html 200 123
(render-page (assoc-ref 'title record) 124
(record-detail-page record)))−116
(http-response/html 404−117
(render-page "Not Found"−118
'(div (h1 "Record Not Found")−119
(p "The record you're looking for doesn't exist.")−120
(a (@ (href "/records")) "Back to collection")))))))+125
(http-response/html 404 (not-found-page))))) 126
127
(define (edit-record-handler req) 128
(let* ((db (db-from-req req))@@ -127,11 +132,7 @@
132
(http-response/html 200 133
(render-page "Edit Record" 134
(record-form-page record #f)))−130
(http-response/html 404−131
(render-page "Not Found"−132
'(div (h1 "Record Not Found")−133
(p "The record you're looking for doesn't exist.")−134
(a (@ (href "/records")) "Back to collection")))))))+135
(http-response/html 404 (not-found-page))))) 136
137
;; ============================================================ 138
;; Action Handlers (POST/DELETE, return SSE batch)@@ -195,9 +196,7 @@
196
(sleep 1) 197
(let* ((db (db-from-req req)) 198
(params (parse-query-params req))−198
(page (or (and (assoc-ref 'page params)−199
(string->number (assoc-ref 'page params)))−200
1))+199
(page (parse-page-param params)) 200
(search (assoc-ref 'q params #f)) 201
(per-page 10) 202
(total (count-records db search))src/sigil/web/demo/db.sglmodified
@@ -73,6 +73,18 @@
73
("Disintegration" "The Cure" 1989 "Alternative" "LP") 74
("Parallel Lines" "Blondie" 1978 "Rock" "7\"")))) 75
+76
;; ============================================================+77
;; Helpers+78
;; ============================================================+79
+80
;; Parse an optional integer from form params.+81
;; Returns the number or #f if missing/empty.+82
(define (parse-optional-int params key)+83
(let ((v (assoc-ref key params)))+84
(if (and v (not (string=? v "")))+85
(string->number v)+86
#f)))+87
88
;; ============================================================ 89
;; CRUD Operations 90
;; ============================================================@@ -112,10 +124,7 @@
124
"INSERT INTO records (title, artist, year, genre, format, notes) VALUES (?, ?, ?, ?, ?, ?)" 125
(assoc-ref 'title params) 126
(assoc-ref 'artist params)−115
(let ((y (assoc-ref 'year params)))−116
(if (and y (not (string=? y "")))−117
(string->number y)−118
#f))+127
(parse-optional-int params 'year) 128
(assoc-ref 'genre params) 129
(or (assoc-ref 'format params) "LP") 130
(assoc-ref 'notes params))@@ -127,10 +136,7 @@
136
"UPDATE records SET title = ?, artist = ?, year = ?, genre = ?, format = ?, notes = ? WHERE id = ?" 137
(assoc-ref 'title params) 138
(assoc-ref 'artist params)−130
(let ((y (assoc-ref 'year params)))−131
(if (and y (not (string=? y "")))−132
(string->number y)−133
#f))+139
(parse-optional-int params 'year) 140
(assoc-ref 'genre params) 141
(or (assoc-ref 'format params) "LP") 142
(assoc-ref 'notes params)src/sigil/web/demo/views.sglmodified
@@ -503,16 +503,8 @@
503
504
;;; Reusable record form fields. 505
(define (record-form record errors)−506
(let ((val (lambda (key)−507
(if record−508
(let ((v (assoc-ref key record #f)))−509
(cond−510
((not v) "")−511
((number? v) (number->string v))−512
(else v)))−513
"")))−514
(err (lambda (key)−515
(if errors (assoc-ref key errors #f) #f))))+506
(let ((val (lambda (key) (and record (assoc-ref key record #f))))+507
(err (lambda (key) (and errors (assoc-ref key errors #f))))) 508
`(div (@ (class "form-fields")) 509
,(sg-text-field name: "title" 510
value: (val 'title)