(define-library (web request-handler) (export sx-url-to-expr sx-auto-quote sx-eval-page sx-handle-request) (begin (define sx-url-to-expr (fn (path) (let ((prefix (cek-try (fn () (or (dict-get __app-config :path-prefix) "/sx/")) (fn (e) "/sx/"))) (prefix-len (len prefix)) (prefix-bare (slice prefix 0 (- prefix-len 1)))) (cond (or (= path "/") (= path prefix) (= path prefix-bare)) "home" (starts-with? path prefix) (join " " (split (slice path prefix-len (len path)) ".")) (starts-with? path "/") (join " " (split (slice path 1 (len path)) ".")) :else path)))) (define sx-auto-quote (fn (expr env) (cond (and (symbol? expr) (not (env-has? env (symbol-name expr)))) (symbol-name expr) (list? expr) (map (fn (e) (sx-auto-quote e env)) expr) :else expr))) (define sx-eval-page (fn (path-expr env) (cek-try (fn () (let ((exprs (sx-parse path-expr))) (when (not (empty? exprs)) (let ((expr (if (= (len exprs) 1) (first exprs) exprs)) (quoted (sx-auto-quote expr env)) (callable (if (symbol? quoted) (list quoted) quoted))) (eval-expr callable env))))) (fn (err) nil)))) (define sx-handle-request (fn (path headers env shell-vars) (let ((is-ajax (or (has-key? headers "sx-request") (has-key? headers "hx-request"))) (path-expr (sx-url-to-expr path)) (page-ast (sx-eval-page path-expr env))) (if (nil? page-ast) nil (let ((prefix (cek-try (fn () (or (dict-get __app-config :path-prefix) "/sx/")) (fn (e) "/sx/"))) (prefix-len (len prefix)) (nav-path (if (and (>= (len path) prefix-len) (= (slice path 0 prefix-len) prefix)) path (str (slice prefix 0 (- prefix-len 1)) path)))) {:page-ast page-ast :nav-path nav-path :is-ajax is-ajax}))))) )) ;; end define-library ;; Re-export to global namespace for backward compatibility (import (web request-handler))