Servlet

Get back to the tutorial page.

The "common" HTML content

The ** function can be very useful. It produces strings from the arguments passed to the function. These strings might be (and usually are) used to produce the content of web pages.

Each argument passed to this function is processed. If the argument is a string, it's left unchanged. Thus

(** "Hello, world")

produces "Hello, world".

If the passed argument is a list, it's changed into an XML string (or whatever it is called; I'm not an XML expert). For example, the list (p "Hello, world!") gives us the string "<p>Hello, world!</p>".

The passed argument can be also a Scheme expression that produces some string. For example:

(** (let ( (x 1) ) (format "X is ~a" x)))

produces the "X is 1" string, since the let form is evaluated.

This way, quote and quasiquote might be used to achieve interesting results. For example, all elements of some list can be formatted as a HTML list:

(define (list-elements lst)
  (** `(ul
        ,(map (lambda (e) (** `(li ,e))) lst))))

But that's not all. Some HTML elements might have their attributes. Let's say, that we want to get the following HTML code:

<a href="some address">some text here</a>

We can achieve it with the following Scheme syntax:

(** '(a ((href "some address")) "some text here"))

But that's not all about the ** function. As I have written, this function might be called with many parameters, and all of them are processed and grouped. It means, that if we wanted to get the following HTML code:

<h1>Some heading</h1>
<p>Some text here.</p>

we could use the ** function as follows:

(** '(h1 "Some heading")
    '(p "Some text here"))

Some practice

Knowing how HTML code can be generated using the ** function, let's make a simple servlet that shows our bookmarks collection. Our goal is to achieve the following content:

<p>Here are my bookmarks:</p>
<ul>
<li><a href="http://leftparen.com">Left Paren home page</a></li>
<li><a href="http://plt-scheme.org">PLT Scheme</a></li>
</ul>

Of course, the list of bookmarks should be generated, not hard-coded.

First, let's place our data in the main.scm file generated by the LeftParen framework:

;; data for our application
(define my-bookmarks
  '(("LeftParen home page" "http://leftparen.com")
    ("PLT Scheme" "http://plt-scheme.org")))

It's a simple list, where all elements are lists of two strings. The first string is the name of a bookmark, and the second element is its address.

Now, let's define the function, which produces list elements in the HTML format for such a Scheme lists:

;; Function that generates the HTML list of the given bookmarks.
(define (bookmarks-list lst)
  (map (lambda (e)
         (** `(li (a ((href ,(cadr e))) ,(car e))))) lst))

Finally, let's change the (generated) content of the index page:

(define-page (index-page req)
  (** '(p "Here are my bookmarks:")
      `(ul ,@(bookmarks-list my-bookmarks))))

And that's all. Our servlet is ready to work.

[To do:

  • Write about web-link function. Of course, I have to learn about it first.
  • Find out what other functions/macros would fit to this chapter.]

Thanks for Rob Hunter for explanation of the ** function.

Get back to the tutorial page.