renaming UTILTIES.SCM to SERVLETS.SCM and structure PLUGIN-UTILITIES to SERVLETS
This commit is contained in:
parent
c28d6cf153
commit
1abbed29f0
|
@ -1,258 +0,0 @@
|
|||
;; utilities for plugin (servlets)
|
||||
;; Copyright 2002, Andreas Bernauer
|
||||
|
||||
(define (send-html/suspend html-tree-maker)
|
||||
(send/suspend
|
||||
(lambda (new-url)
|
||||
(make-usual-html-response
|
||||
(lambda (out options)
|
||||
(servlet-XML->HTML out (html-tree-maker new-url)))))))
|
||||
|
||||
(define (send-html/finish html-tree)
|
||||
(do-sending send/finish html-tree))
|
||||
|
||||
(define (send-html html-tree)
|
||||
(do-sending send html-tree))
|
||||
|
||||
(define (do-sending send html-tree)
|
||||
(send (make-usual-html-response
|
||||
(lambda (out options)
|
||||
(servlet-XML->HTML out html-tree)))))
|
||||
|
||||
(define (make-usual-html-response writer-proc)
|
||||
(make-response
|
||||
http-status/ok
|
||||
(status-code->text http-status/ok)
|
||||
(time)
|
||||
"text/html"
|
||||
'()
|
||||
(make-writer-body writer-proc)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; from cgi-script:
|
||||
;;; Return the form data as an alist of decoded strings.
|
||||
;;; So a query string like "button=on&reply=Oh,%20yes" becomes alist
|
||||
;;; (("button" . "on") ("reply" . "Oh, yes"))
|
||||
;;; This only works for GET and POST methods.
|
||||
|
||||
(define form-query parse-html-form-query)
|
||||
|
||||
(define (extract-bindings bindings key)
|
||||
(let ((key (if (symbol? key) (symbol->string key) key)))
|
||||
(filter (lambda (binding)
|
||||
(equal? (car binding) key))
|
||||
bindings)))
|
||||
|
||||
(define (extract-single-binding bindings key)
|
||||
(let ((key-bindings (extract-bindings bindings key)))
|
||||
(if (= 1 (length key-bindings))
|
||||
(cdar key-bindings)
|
||||
(error "extract-one-binding: more than one or zero bindings found"
|
||||
(length key-bindings)
|
||||
key bindings))))
|
||||
|
||||
|
||||
;; adapted from Oleg's SXML-tree-trans.scm
|
||||
;; extended by port argument
|
||||
;; #t: current-output-port
|
||||
;; #f: string
|
||||
;; port: port
|
||||
;; else: error
|
||||
(define (formated-reply port . fragments)
|
||||
(cond
|
||||
((not port)
|
||||
(call-with-string-output-port
|
||||
(lambda (port)
|
||||
(real-formated-reply port fragments))))
|
||||
((eq? port #t)
|
||||
(real-formated-reply (current-output-port) fragments))
|
||||
((output-port? port)
|
||||
(real-formated-reply port fragments))
|
||||
(else
|
||||
(error "invalid port argument to FORMATED-REPLY" port))))
|
||||
|
||||
(define (real-formated-reply port fragments)
|
||||
(let loop ((fragments fragments) (result #f))
|
||||
(cond
|
||||
((null? fragments) result)
|
||||
((not (car fragments)) (loop (cdr fragments) result))
|
||||
((null? (car fragments)) (loop (cdr fragments) result))
|
||||
((pair? (car fragments))
|
||||
(loop (cdr fragments) (loop (car fragments) result)))
|
||||
((procedure? (car fragments))
|
||||
((car fragments))
|
||||
(loop (cdr fragments) #t))
|
||||
(else
|
||||
(display (car fragments) port)
|
||||
(loop (cdr fragments) #t)))))
|
||||
|
||||
;; adapted from Oleg's SXML-to-HTML.scm
|
||||
;; extended by additional port argument
|
||||
(define (servlet-XML->HTML out html-tree)
|
||||
(formated-reply out
|
||||
(pre-post-order html-tree
|
||||
;; Universal transformation rules. Work for every HTML,
|
||||
;; present and future
|
||||
`(,@default-rules
|
||||
(form *preorder* .
|
||||
,(lambda (trigger call-back-function . elems)
|
||||
(list "<form method=\"GET\" action=\"" call-back-function
|
||||
(if (and (pair? elems) (pair? (car elems)) (eq? '@ (caar elems)))
|
||||
(list (car elems) "\">\n" (parse-form-elems (cdr elems)) "</form>")
|
||||
(list "\">\n" (parse-form-elems elems) "</form>"))))))
|
||||
|
||||
)))
|
||||
|
||||
(define (parse-form-elems elems)
|
||||
(map (lambda (elem)
|
||||
(if (input-field? elem)
|
||||
(post-order (input-field-HTML-tree elem) default-rules)
|
||||
(post-order elem default-rules)))
|
||||
elems))
|
||||
|
||||
(define text-html-rule
|
||||
`(*text* . ,(lambda (trigger str)
|
||||
(if (string? str) (string->goodHTML str) str))))
|
||||
(define default-rules
|
||||
`((@ ; local override for attributes
|
||||
((*default*
|
||||
. ,(lambda (attr-key . value) ((enattr attr-key) value))))
|
||||
. ,(lambda (trigger . value) (list '@ value)))
|
||||
(*default* . ,(lambda (tag . elems) (apply (entag tag) elems)))
|
||||
,text-html-rule
|
||||
(URL . ,(lambda (tag URI text) (list "<a href=\"" URI "\">" text "</a>"))))
|
||||
)
|
||||
|
||||
(define (make-callback function)
|
||||
(call-with-current-continuation
|
||||
(lambda (exit)
|
||||
(let* ((req (send/suspend (lambda (new-url)
|
||||
(exit new-url))))
|
||||
(bindings (form-query (http-url:search (request:url req)))))
|
||||
(function bindings)))))
|
||||
|
||||
(define-record-type input-field :input-field
|
||||
(make-input-field name transformer HTML-tree)
|
||||
input-field?
|
||||
(name input-field-name)
|
||||
(transformer input-field-transformer)
|
||||
(attributes input-field-attributes)
|
||||
(HTML-tree input-field-HTML-tree))
|
||||
|
||||
(define-record-discloser :input-field
|
||||
(lambda (input-field)
|
||||
(list 'input-field (input-field-name input-field))))
|
||||
|
||||
;; FIXME: consider creating small names
|
||||
(define generate-input-field-name
|
||||
(let ((id 0))
|
||||
(lambda (type-string)
|
||||
(set! id (+ 1 id))
|
||||
(string-append type-string (number->string id)))))
|
||||
|
||||
(define identity (lambda (a) a))
|
||||
|
||||
(define (make-text-input-field . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "text")))
|
||||
(make-input-field name
|
||||
identity
|
||||
`(input (@ (type "text")
|
||||
(name ,name)
|
||||
,@maybe-further-attributes)))))
|
||||
|
||||
(define (make-number-input-field . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "number")))
|
||||
(make-input-field name
|
||||
(lambda (string)
|
||||
(or (string->number string)
|
||||
(error "wrong type")))
|
||||
`(input (@ (type "text")
|
||||
(name ,name)
|
||||
,@maybe-further-attributes)))))
|
||||
|
||||
(define (make-password-input-field . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "password")))
|
||||
(make-input-field name
|
||||
identity
|
||||
`(input (@ (type "password")
|
||||
(name ,name)
|
||||
,@maybe-further-attributes)))))
|
||||
|
||||
(define (make-textarea-input-field . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "textarea"))
|
||||
(default-text (if (and (pair? maybe-further-attributes)
|
||||
(string? (car maybe-further-attributes)))
|
||||
(car maybe-further-attributes)
|
||||
'())))
|
||||
(make-input-field name
|
||||
identity
|
||||
`(textarea (@ (type "textarea")
|
||||
(name ,name)
|
||||
,@maybe-further-attributes)
|
||||
,default-text))))
|
||||
|
||||
(define (make-select-input-field options . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "select")))
|
||||
(make-input-field name
|
||||
(lambda (select)
|
||||
select) ;FIXME[extension] refer to list elements
|
||||
`(select (@ ((name ,name)
|
||||
,@maybe-further-attributes))
|
||||
#\newline
|
||||
,@(map (lambda (option)
|
||||
(if (pair? option) ; with attributes?
|
||||
`(option (@ ,@(cdr option)) ,(car option))
|
||||
`(option ,option)))
|
||||
options)))))
|
||||
|
||||
;; in work
|
||||
(define (make-radio-input-field values . maybe-further-attributes)
|
||||
(let ((name (generate-input-field-name "radio")))
|
||||
(make-input-field name
|
||||
(lambda (select)
|
||||
select) ;FIXME refer to list elements
|
||||
(map (lambda (value)
|
||||
`((input (@ ((type "radio")
|
||||
(name ,name)
|
||||
,@maybe-further-attributes
|
||||
,(if (pair? value) ; with attributes?
|
||||
(cdr value)
|
||||
'())))) ;FIXME: add value field
|
||||
,(if (pair? value) ; with attributes?
|
||||
(car value)
|
||||
value)))
|
||||
values))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(define (make-submit-button . maybe-further-attributes)
|
||||
(if (and (pair? maybe-further-attributes)
|
||||
(string? (car maybe-further-attributes)))
|
||||
`(input (@ (type "submit")
|
||||
(value ,(car maybe-further-attributes))
|
||||
,@maybe-further-attributes))
|
||||
`(input (@ (type "submit")
|
||||
,@maybe-further-attributes))))
|
||||
|
||||
(define (input-field-value input-field bindings)
|
||||
(cond
|
||||
((assoc (input-field-name input-field) bindings) =>
|
||||
(lambda (binding)
|
||||
((input-field-transformer input-field) (cdr binding))))
|
||||
(else
|
||||
(error "no such input-field" input-field bindings))))
|
||||
|
||||
|
||||
(define number-input-field (make-number-input-field))
|
||||
|
||||
(define test
|
||||
`(html
|
||||
(title "My Title")
|
||||
(body
|
||||
(p (URL "reset" "click here to reset"))
|
||||
(p (form "return-URI" (table (tr (td "Enter a number ") (td ,number-input-field )))
|
||||
,(make-submit-button))))))
|
||||
|
Loading…
Reference in New Issue