Fast HTML templates for Racket servlets with include-template

Templates are the bread and butter of web development. As with many things in Racket, there's more than one way of doing things, and it's not always easy to keep all of them straight. I myself use a mixture of approaches, depending on my needs. In another tutorial, I talked a bit about about txexpr. Here's a brief description of another approach to HTML generation, include-template, that has some nice advantages and is definitely worth knowing about.

Briefly, include-template takes a file and makes a function that, given some variables as arguments, produces a string. It's fast and simple. Let's cut straight to an example:

<!doctype html>
<html lang="en">
    <title>Rational numbers are awesome</title>
    <p>Today I learned that the reciprocal of @|n|
is @|r|.</p>

Store that in a file, say, reciprocal.html and include it in your web program with

(include-template "reciprocal.html")

(Don't forget to include

(require web-server/templates)

in your code. That's where include-template comes from.)

The variables n and r show up in the template, here using the Scribble @ notation (and, moreover, surrounded by pipes |) are Racket identifiers. They should be in lexical scope wherever you do include-template. Here's a complete example:

(let* ([n 5]
       [r (/ 1 n)])
  (include-template "reciprocal.html"))

The values for n and r are hardcoded here, but could come from anywhere. (Perhaps data coming from an HTTP POST request?)

Some noteworthy features of the Scribble-based approach: