Version: 4.1.1

4.1 Basic Formlet Usage

Suppose we want to create an abstraction of entering a date in an HTML form. The following formlet captures this idea:

  (define date-formlet

    (formlet

     (div

      "Month:" ,{input-int . => . month}

      "Day:" ,{input-int . => . day})

     (list month day)))

The first part of the formlet syntax is the template of an X-expression that is the rendering of the formlet. It can contain elements like ,(=> formlet name) where formlet is a formlet expression and name is an identifier bound in the second part of the formlet syntax.

This formlet is displayed (with formlet-display) as the following X-expression forest (list):

  (list

   '(div "Month:" (input ([name "input_0"]))

         "Day:" (input ([name "input_1"]))))

date-formlet not only captures the rendering of the form, but also the request processing logic. If we send it an HTTP request with bindings for "input_0" to "10" and "input_1" to "3", with formlet-process, then it returns:

  (list 10 3)

which is the second part of the formlet syntax, where month has been replaced with the integer represented by the "input_0" and day has been replaced with the integer represented by the "input_1".

The real power of formlet is that they can be embedded within one another. For instance, suppose we want to combine two date forms to capture a travel itinerary. The following formlet does the job:

  (define travel-formlet

    (formlet

     (div

      "Name:" ,{input-string . => . name}

      (div

       "Arrive:" ,{date-formlet . => . arrive}

       "Depart:" ,{date-formlet . => . depart})

     (list name arrive depart))))

(Notice that date-formlet is embedded twice.) This is rendered as:

  (list

   '(div

     "Name:"

     (input ([name "input_0"]))

     (div

      "Arrive:"

      (div "Month:" (input ([name "input_1"]))

           "Day:" (input ([name "input_2"])))

      "Depart:"

      (div "Month:" (input ([name "input_3"]))

           "Day:" (input ([name "input_4"]))))))

Observe that formlet-display has automatically generated unique names for each input element. When we pass bindings for these names to formlet-process, the following list is returned:

  (list "Jay"

        (list 10 3)

        (list 10 6))

The rest of the manual gives the details of formlet usage and extension.