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.