[racket] Dynamic Templates?

From: Joe Gibbs Politz (joe at cs.brown.edu)
Date: Wed Jun 5 15:53:55 EDT 2013

I'm writing a web server in a #lang that doesn't support macros or
syntactic abstraction.  I would like to be able to use some sort of
templating dynamically with bindings given by values, e.g.

template.render("page-with-hole-for-username.html", { username: "Joe" })

The FAQ (http://docs.racket-lang.org/web-server/faq.html#(part._.How_do_.I_use_templates__dynamically__))
in the documentation for templates ends with this pithy
recommendation:

"If you insist on dynamicism, there is always eval."

I assume this isn't intended seriously, and instead to discourage what
I'm asking about, but I'm unfortunately not seeing another way to
write my program.  The code at the end of this message seems like the
best I can do while being relatively safe, but also like a dubious
inclusion on a web server given the eval.

Is this the best I can hope for?  Is there another collection I should
be looking into?  Any other recommendations?

Thanks!
Joe P.


#lang racket/base

(require
  web-server/templates)

(define (render-template filename dict)
  (define namespace-for-template (make-empty-namespace))
  (namespace-attach-module (current-namespace) 'web-server/templates
namespace-for-template)
  (hash-map dict
    (lambda (key value)
      (define name-of-identifier (string->symbol key))
      (namespace-set-variable-value!
        name-of-identifier
        value
        #f
        namespace-for-template)))
  (parameterize [(current-namespace namespace-for-template)]
    (namespace-require 'web-server/templates))
  (define to-eval #`(include-template #,(datum->syntax
#'render-template filename)))
  (eval to-eval namespace-for-template))

Posted on the users mailing list.