{ (define LIBNAME "Simplified Scheme Web Servlets") (include "head.tinc") }
This teachpack provides a simplified API for PLT Scheme servlets. The teachpack does not require any understanding of HTML and higher-order functions. It uses structures and lists, and is therefore well-suited for use with an HtDP course.
; Data Constructors ------------------------------------------------------- {(idx make-password)} ; asking for a password {(idx make-number)} ; asking for a number {(idx make-yes-no)} ; asking for a Yes-No style answer {(idx make-boolean)} ; asking for a true-false style answer {(idx make-radio)} ; requesting one choice from some mutually exclusive choices #| Data Definitions -------------------------------------------------------- Forms ---------------------------------------------------------------------- Query = (union String (make-password String) (make-number String) (make-boolean String) (make-yes-no String String String) (make-radio String (cons String (listof String)))) FormItem = (list Symbol Query) Form = (cons FormItem (listof FormItem)) Table ------------------------------------------------------------------- Response = (union String Number Boolean) Table = (listof (list Symbol Response)) |# ; Functions ---------------------------------------------------------------- {(idx form?)} ; TST -> Boolean ; checking the structure of forms {(idx form-element?)} ; TST -> Boolean ; checking the structure of form-elements {(idx single-query)} ; Query -> Response ; posing a single question {(idx queries)} ; (listof Query) -> (listof Response) ; posing a list of questions {(idx echo-answers)} ; (listof Response) -> true ; echoing the answers from a list of questions to a Web page (development) {(idx form-query)} ; Form -> Table ; posing a list of questions with tag {(idx extract/single)} ; Symbol Table -> Response ; extracting the answer for a given tag from a response; the tag must ; occur exactly once. {(idx extract)} ; Symbol Table -> (listof Response) ; extracting all the answers for a given tag from a response; the list ; is empty if there is no such tag. {(idx echo-response)} ; Table -> true ; echoing the response from a form to a Web page (development) {(idx inform)} ; String String *-> true ; posting some information on a Web page, wait for continue signal {(idx final-page)} ; String String *-> true ; posting some information on a Web page, ; killing the script and all associated backtrack/clone points
The following table specifies what kind of answer each form of query produces:
Query GUI Item Response ________________________________________________________________________________ String text field String (make-password String) password field String (make-number String) text field Number (make-boolean String) check box Boolean (make-yes-no String String1 String2) 2-pronged radio String1 or String2 (make-radio String loString) radio button one of loString (make-button String0) submit button String0
The functions play the following role:
form?
and form-element?
enable programmers to
check the well-formedness of their queries.
single-query
poses a question and waits for a answer from
the consumer.
queries
poses a list of questions and waits for the
submission of answers; it produces a list of answers that is as
long as the list of given questions.
echo-answers
echoes a list of answers to a Web page; this
function is useful for testing Web form designs.
form-query
poses a form with queries and waits for the
submission of answers; it produces a list of tagged or labeled answers
that is as long as the list of given questions.
echo-response
echoes a response to a Web page as a table.
inform
posts some information on a Web page and wait for a
continue signal (a link) from the consumer; the first string plays the
role of a title and the rest form a paragraph.
final-page
posts some information on a Web page and
shuts down the script and all associated backtrack/clone points.
The following example illustrates how the library enables programs to
interact with the consumer. In particular, note the properly recursive
calls to login
in inform-error
. Also note how the
primitives make-password
and make-number
deliver
strings and numbers, respectively.
#| Login Site ----------------------------------------------------------------- Author: Matthias Felleisen Language: Intermediate Teachpack: servlet2.ss Login Web Site: A login site consists of three pages: 1. login: request user information: name, password, year-of-birth - if correct, respond with greeting for name - if incorrect, go to error page 2. error: inform user of error, continue goes back to login page 3. greetings: say hello to name The second and third are generated from user input, the first is generated by the program alone. |# ;; Login Page ----------------------------------------------------------------- ; ask three questions: one plain, one password, one numeric (define login-page (list (list 'name "User Name") (list 'pass (make-password "Password")) (list 'yofb (make-number "Year-of-birth")))) ; Table -> true ; process the response for login-page (define (login r) (let ([name (extract/single 'name r)]) (if (string=? (lookup-password name) (extract/single 'pass r)) (if (= (lookup-yofb name) (extract/single 'yofb r)) (greetings name) (inform-error "bad data")) (inform-error "bad match")))) ; String -> (union false String) ; lookup the password for name in DB (define (lookup-password name) (local ([define (x=? x) (string=? name x)] [define r (assf x=? DB)]) (if (boolean? r) false (second r)))) ; String -> (union false Number) ; lookup the year-of-birth for name in DB (define (lookup-yofb name) (local ([define (x=? x) (string=? name x)] [define r (assf x=? DB)]) (if (boolean? r) false (third r)))) (define DB '(("matthias" "okay" 1958))) ;; Error Page ----------------------------------------------------------------- ; String -> true ; consume error message, print and enable return to login page (define (inform-error s) (let ([_ (inform "Error" s)]) (login (form-query login-page)))) ;; Greetings Page ------------------------------------------------------------- ; String -> true ; consume name and display good bye message (define (greetings name) (inform "Welcome" "Welcome " name " and good bye.")) ;; RUN ------------------------------------------------------------------------ (login (form-query login-page)){(include "foot.tinc")}