[racket] Dynamic Templates?
While it is supposed to be pithy, it is also serious.
When I wrote it, I imagine that people would do something like this:
#lang racket/base
(require web-server/templates)
(define (template-content t x)
(eval #`(let ([x #,x]) (include-template #,t))))
(template-content "t.txt" 5)
(template-content "t.txt" 6)
and trust that the template wouldn't include @(system "rm -fr /"). I
think that a simple eval works just fine for when you, the programmer,
want to change the content dynamic (although I'd say it is better to
use the web-server language so you can restart with the same
continuations, etc.)
Your solution is great for a template that a user provides, although
it has the hole that the template could call @include-template and
maybe find itself and go into a infinite loop, so it's not totally
"secure" unless you use a sandbox.
Jay
On Wed, Jun 5, 2013 at 1:53 PM, Joe Gibbs Politz <joe at cs.brown.edu> wrote:
> 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))
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
--
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay
"The glory of God is Intelligence" - D&C 93