1 What Flavor Would You Like?

We all like ice cream don’t we? Let’s build a website for taking orders for ice cream.

#lang web-server/insta
(define (start request)
  (response/xexpr
   '(html
     (head (title "Ice Cream In My Tummy!"))
     (body (h1 "Ice Cream In My Tummy!")))))

Using the insta language will simplify things for us here. Hopefully it will be obvious that S-expressions are translated into html.

Put that code in DrRacket and press Run.

Everything begins in the start function (dur-hay!). Or perhaps everything begins and ends in the start function. Let’s imagine the simplest possible ordering page. One in which the user selects a flavor, and the system tells that user what they ordered. What might the last page look like:

<html>
    <body bgcolor="white">
        <p>
              You ordered: Vanilla
              </p>
    </body>
</html>

Given that we have already conjured up the end result, why don’t we start there? We know we want to see something like, "You ordered: Vanilla", but we don’t know what to display until the user selects a flavor. This is where the quasiquote comes in.

#lang web-server/insta
(define (request-flavor)
  "Vanilla")
 
(define (start request)
  (response/xexpr
   `(html
     (body ((bgcolor "white"))
           (p "You ordered: "
              ,(request-flavor))))))

The quasiquote creates a hole in the string for the value of request-flavor. Without the quasiquote, we would get:

<html>
    <body bgcolor="white">
        <p>You ordered: <the-ordered-flavor /></p>
    </body>
</html>

Definitely not what we wanted! The quasiquote form allows us to say, "Print this literally except where the commas appear."

(define (request-flavor)
  (extract-binding/single
   'flavor
   (request-bindings
    (send/suspend
     (lambda (k-url)
       (response/xexpr
        `(html (head (title "Pick a Flavor"))
          (body ([bgcolor "white"])
                (form ([action ,k-url] [method "post"])
                      (input ((type "radio")
                              (name "flavor")
                              (value "vanilla"))) "Vanilla" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "chocolate"))) "Chocolate" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "strawberry"))) "Strawberry" (br)
                      (input ([type "submit"]
                              [name "submit"]
                              [value "Submit"])))))))))))
 
(define (start request)
  (response/xexpr
   `(html
     (body ((bgcolor "white"))
           (p "You ordered: "
              ,(request-flavor))))))

Before you go on, add more flavors to our form.

(define (request-flavor)
  (extract-binding/single
   'flavor
   (request-bindings
    (send/suspend
     (lambda (k-url)
       (response/xexpr
        `(html (head (title "Pick a Flavor"))
          (body ([bgcolor "white"])
                (form ([action ,k-url] [method "post"])
                      (input ((type "radio")
                              (name "flavor")
                              (value "vanilla"))) "Just Vanilla" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "chocolate"))) "Chocolate" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "strawberry"))) "Strawberry" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "coffee"))) "Coffee" (br)
                      (input ((type "radio")
                              (name "flavor")
                              (value "sweat cream"))) "Sweat Cream" (br)
                      (input ([type "submit"]
                              [name "submit"]
                              [value "Submit"])))))))))))
 
(define (start request)
  (response/xexpr
   `(html
     (body ((bgcolor "white"))
           (p "You ordered: "
              ,(request-flavor))))))

Here in Austin, we have Amy’s Ice Cream. If you ask them nicely, they will add extra ingredients to your order.

(define (start initial-request)
  (response/xexpr
   `(html
     (body ([bgcolor "white"])
           (p "You ordered: "
              ,(request-flavor)
              )
           (p " and you wanna crush in some:  "
              ,(request-crush-in)
           )))))

request-crush-in will be very similar to request-flavor:

(define (request-crush-in)
  (extract-binding/single
   'crush-in
   (request-bindings
    (send/suspend
     (lambda (k-url)
       (response/xexpr
        `(html (head (title "Pick a Flavor"))
          (body ([bgcolor "white"])
                (form ([action ,k-url] [method "post"])
                      (input ((type "radio")(name "crush-in")(value "Grape-Nuts")(checked "true"))) "Grape-Nuts" (br)
                      (input ((type "radio")(name "crush-in")(value "Strawberries"))) "Strawberries" (br)
                      (input ((type "radio")(name "crush-in")(value "Almonds"))) "Almonds" (br)
                      (input ([type "submit"] [name "submit"] [value "Submit"])))))))))))