BTW here's the technique I devised, in case it's useful to others. ; define the values you need for include-template (define body-for-template "content") (define template-name "template.html")
(define page-result (parameterize ([current-namespace (make-base-empty-namespace)] [current-directory source-dir] ; set this to your template directory if you want to use relative names in include-template [current-output-port (open-output-nowhere)]) (namespace-require 'racket) (eval '(require web-server/templates) (current-namespace)) ; repeat as needed for other modules your template uses (eval `(define body ',body-for-template) (current-namespace)) ; repeat as needed to establish your template variables (eval `(include-template #:command-char #\∂ ,template-name) (current-namespace)))) ; I use ∂ as exp delimiter ; go on to do things with page-result ... BTW thanks again to Jay McCarthy for adding the command-char option to include-templates, which makes it possible to have compile-time expressions and run-time expressions in the templates, and also avoid escaping @ symbols. On Wed, May 15, 2013 at 8:43 AM, Matthew Butterick <mb.list.a...@gmail.com>wrote: > Probably more products should have an FHQ (Frequently Hopeless Questions) > in addition to an FAQ. > > I'm making a web-page generator that uses include-template from > web-server/templates. I need to set the template inputs & the template > itself at runtime, and collect the output. > > I tried doing it with module and module* but I didn't see how to make the > data go round-trip. A submodule with include-template could require the > needed data from the enclosing module, but then the enclosing module can't > require the submodule to get the result, so ... ? I could well be > overlooking an obvious technique. > > My original solution was to write a new file and send it through the > Racket executable as a system command. (This worked, slowly.) > > So that's how I ended up using eval. Which does work, now that I've > retooled how I set up the namespace. > > > On Tue, May 14, 2013 at 5:13 PM, Robby Findler < > ro...@eecs.northwestern.edu> wrote: > >> The short answer is that the top-level is hopeless, as Matthew has >> discussed at some length here and elsewhere. >> >> If you really need to eval code, can you first put it into a module? >> >> Robby >> >> >> On Tue, May 14, 2013 at 11:09 AM, Matthew Butterick < >> mb.list.a...@gmail.com> wrote: >> >>> Suppose x-is-foo.rkt is this: >>> >>> (module x-is-foo racket >>> (define x 'foo) >>> (provide x)) >>> >>> If you open another file and try this: >>> >>> (require "x-is-foo.rkt") >>> (define x 'bar) >>> >>> You'lll get a "identifier already imported" error. OK, that much I >>> understand. >>> >>> Here's the question. When you do this: >>> >>> (parameterize ([current-namespace (make-base-empty-namespace)]) >>> (namespace-require 'racket) >>> (namespace-require "x-is-foo.rkt") >>> (namespace-set-variable-value! 'x 'bar) >>> (eval '(print x) (current-namespace))) >>> >>> This time, you get 'foo. Why 'foo? Why not another "identifier already >>> imported" error? >>> >>> I assume I'm missing a subtlety of how the namespace environment is >>> different. But according to the docs, both namespace-require and >>> namespace-set-variable-value! affect the top-level environment of the >>> namespace. So I don't see why the require is silently overriding the >>> set-variable-value, rather than causing a conflict. >>> >>> It's not a sequencing issue, because if you swap the two lines: >>> >>> (parameterize ([current-namespace (make-base-empty-namespace)]) >>> (namespace-require 'racket) >>> (namespace-set-variable-value! 'x 'bar) >>> (namespace-require "x-is-foo.rkt") >>> (eval '(print x) (current-namespace))) >>> >>> You still get 'foo. >>> >>> Only if you remove the require line: >>> >>> (parameterize ([current-namespace (make-base-empty-namespace)]) >>> (namespace-require 'racket) >>> (namespace-set-variable-value! 'x 'bar) >>> (eval '(print x) (current-namespace))) >>> >>> Do you get 'bar. >>> >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >>> >> >
____________________ Racket Users list: http://lists.racket-lang.org/users