Peony Web Framework
1 Full Example
2 Reference
page
webapp
webpage
7.7

Peony Web Framework

 (require peony) package: peony

Peony is a small frontend on Web Applications in Racket which makes web development fit closer to the idiom familiar to people who’ve mainly used php or similar in the past. With Peony, each webpage lives at a fixed path and corresponds to a chunk of code that’s executed to produce html when the page is accessed. As long as that’s all that’s needed, the details of dispatching and such can be avoided.

See also DB: Database Connectivity.

1 Full Example

As an example of use, say we want to create a webapp to demonstrate the use of GET and POST parameters.

First, we can set up a main page like so:
(define index (page index.html
                    '(html (body (h1 "demo webapp")
                                 (a [[href "demos/get"]] "test get")
                                 (br)
                                 (a [[href "demos/post"]] "test post")))))
Which defines index as a webpage with the path index.html and a static body. Since we’ll be using it as the index of our webapp it will be accessible at www.address.com/. we call it index.html just for the sake of tradition, since it has to have a non-empty name as well.

The GET page can be implemented using the GET binding like so:
(define getpage (page demos/get
                      `(html (body (h1 "GET demo")
                                   (form [[method "get"]]
                                         (p "submit a GET request with paramenters:")
                                         (p "p1: " (input [[type "text"][name "p1"]]))
                                         (p "p2: " (input [[type "text"][name "p2"]]))
                                         (br)
                                         (button "submit"))
                                   (table
                                    (tr (th "Name") (th "Value"))
                                    ,@(hash-map GET (λ (key val) `(tr (td ,key) (td ,val)))))
                                   (a [[href "index.html"]] "back")))))
(where ",@" is unquote-splicing). The resulting page is generated with new GET values each time it’s loaded.

The POST page can be identical except for replacing each instance of ’get’ with ’post’ (noting that the one referencing the actual binding must be all-caps POST):
(define postpage (page demos/post
                      `(html (body (h1 "POST demo")
                                   (form [[method "post"]]
                                         (p "submit a POST request with paramenters:")
                                         (p "p1: " (input [[type "text"][name "p1"]]))
                                         (p "p2: " (input [[type "text"][name "p2"]]))
                                         (br)
                                         (button "submit"))
                                   (table
                                    (tr (th "Name") (th "Value"))
                                    ,@(hash-map POST (λ (key val) `(tr (td ,key) (td ,val)))))
                                   (a [[href "index.html"]] "back")))))

Then we can put it all together into a webapp and serve it:
(define app (webapp index getpage postpage))
(serve/servlet app #:servlet-regexp #rx"" #:servlet-path "")
serve/servlet with #:servlet-regexp #rx"" and #:servlet-path "" is equivalent to serve/dispatch, but doing it this way allows us to add other serve/servlet-specific parameters later (such as #:start-web-browser? and #:port).

2 Reference

syntax

(page name contents)

 
  name : symbol?
  contents : xexpr?
Returns a webpage whose path is name and whose body is a Web Applications in Racket servlet - a function taking an http request and returning a response. The response is a standard 200 response whose body consists of the html corresponding to the provided contents. The contents expression has access to four values: GET, POST, COOKIE and REQ, containing respectively a hash mapping GET arguments to their values, a hash mapping POST arguments to their values, a hash mapping cookies to their values, and the literal request in full. In GET, POST and COOKIE, if there are multiple parameters with the same name then the earlier ones are shadowed by the later ones, the full query can be extracted by manually processing REQ if this is a problem.

procedure

(webapp index pages ...)  (-> request? response?)

  index : webpage?
  pages : webpage?
Returns a servlet that can be passed to Web Applications in Racket’s serve/dispatch (or similar, but the servlet-regexp must be #rx"" in any case). The servlet serves each page at the url matching its path, and a fixed 404 page at all other paths. The first page, the index, is also served at the empty path.

struct

(struct webpage (path body)
    #:extra-constructor-name make-webpage)
  path : symbol?
  body : (-> request? response?)
A structure for webpages, consisting of a path the page can be found at and a function mapping an http request to a response. The page form generates slightly limited webpages automatically.