[plt-scheme] Formlets in PLT

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Tue Sep 16 18:59:22 EDT 2008

The Links group has created formlets:


I have spent the afternoon implementing formlets in PLT.

In the latest SVN, there is a web-server/formlets directory with a
'formlets' module.

Here is a simple example:

==== Define some basic functions & structures

#lang scheme
(require web-server/formlets/formlets)

(define-struct date (month day))
(define (date->xml d)
  (format "~a/~a"
          (date-month d)
          (date-day d)))

(define (submit t)
  `(input ([type "submit"]) ,t))

==== Now for the first formlet:

(define date-formlet
    "Month:" ,{input-int . => . month}
    "Day:" ,{input-int . => . day})
   (make-date month day)))

==== The first part is the display of the formlet, the second is how
it should be processed. The => syntax tells the formlet macro that
month and day should be bound in the processor as the result of
inputing integers.

(formlet-display date-formlet)

==== Displaying this formlet returns the following xexpr forest (list):

((div () "Month:" (input ((name "input_0"))) "Day:" (input ((name "input_1")))))

==== The input names are automatically generated.

==== Formlets can be composed:

(define travel-formlet
    "Name:" ,{input-string . => . name}
     "Arrive:" ,{date-formlet . => . arrive}
     "Depart:" ,{date-formlet . => . depart})
    ,@(list "1" "2" "3")
    ,(submit "Submit"))
   (list name arrive depart)))

==== The #%# is to note an xexpr forest. Notice that date-formlet is
used to embed the date formlet twice in the travel formlet. The
display portion of a formlet is implicitly in a quasiquote, so ,@ and
, work as before.

(formlet-display travel-formlet)

==== The travel formlet is displayed as follows:

 (input ((name "input_0")))
  (div () "Month:" (input ((name "input_1"))) "Day:" (input ((name "input_2"))))
  (div () "Month:" (input ((name "input_3"))) "Day:" (input ((name
 (input ((type "submit")) "Submit"))

==== Notice the input names are guaranteed to not conflict.

==== Let's embed this formlet into a web page that does the following
with the result:

(define display-itinernary
    [(list name arrive depart)
       (head (title "Itinerary"))
        "Itinerary for: " ,name
        "Arriving:" ,(date->xml arrive)
        "Departing:" ,(date->xml depart)))]))

==== This provides send/formlet, which wraps a formlet in send/suspend
(require web-server/formlets/servlet)

(define (start request)

==== embed-formlet is also available to put a formlet inside of


Currently formlet combinators are provided for input-string,
input-integer, and input-symbol. More will come as the library is
used. I also plan on working on input validation, etc.


Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.