By the way, one gotcha with at-exp templates is that they're not aware what a comment is, in the target language e.g. HTML. For example:
<!-- I am a helpful comment in example-template.html explaining that @FOO is a template variable for foo-ish stuff. --> <p>@FOO</p> Will expand when FOO is "HEY HEY HEY" to: <!-- I am a helpful comment in example-template.html explaining that HEY HEY HEY is a template variable for foo-ish stuff. --> <p>HEY HEY HEY</p> Although that result _works_, even when @FOO is very lage with many newlines, it's a bit confusing and wasteful to have such a huge comment. At first glance you think "Oh no, it ended up in the comment _instead_", then you realize, "Ah, it ended up in the comment _and_ outside the comment". p.s. Yes you could @-escape it in the comment, but then the comment isn't saying exactly what to use. On Thu, Jun 6, 2013 at 10:36 PM, Greg Hendershott <greghendersh...@gmail.com> wrote: > Great timing! It's been on my short list to make my static blog > generator more flexible. From > http://docs.racket-lang.org/web-server/templates.html I got the idea > that it would be suitable only for static templates, but now I > understand that's not the case. Today I made a topic branch using this > approach that's working well, which I plan to merge after some testing > and polishing. > > p.s. Maybe it's obvious, but because `include-template` uses > `include-at/relative-to/reader`, it won't include a template if you > give it a full path. Maybe there's a more-elegant way, but I found it > worked to parameterize `current-directory` around the call to `eval`. > > > On Wed, Jun 5, 2013 at 4:45 PM, Jay McCarthy <jay.mccar...@gmail.com> wrote: >> 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 <j...@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 <j...@cs.byu.edu> >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users