[racket] Dynamic Templates?
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
<greghendershott at 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.mccarthy at 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 <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
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users