Templates Racket Web服务器/模板包含模板不能与变量一起使用

Templates Racket Web服务器/模板包含模板不能与变量一起使用,templates,servlets,racket,procedure,keyword-argument,Templates,Servlets,Racket,Procedure,Keyword Argument,我正在使用Racket web服务器写一个小博客(需要web服务器/模板、web服务器/servlet环境、web服务器/servlet、web服务器/dispatch)。每当我要渲染模板时,我都会执行以下操作: (define (render-homeworks-overview-page) (let ([dates (sort (get-all-homework-dates) #:key my-date->string

我正在使用Racket web服务器写一个小博客(需要
web服务器/模板、web服务器/servlet环境、web服务器/servlet、web服务器/dispatch
)。每当我要渲染模板时,我都会执行以下操作:

(define (render-homeworks-overview-page)
  (let
    ([dates
       (sort
         (get-all-homework-dates)
         #:key my-date->string
         string<?)])
    (include-template "templates/homework-overview.html")))
这将为模板中显示的内容提供一个默认值,并为模板提供一个默认路径来呈现和获取任意关键字参数,因此任何呈现过程都可以通过将模板作为关键字来提供模板所需的任何内容

但是,我无法运行此代码,因为出现错误:

include-at/relative-to/reader: not a pathname string, `file' form, or `lib' form for file
调用
(包括模板路径)
中的
模板路径
带有红色下划线,表示存在错误。但是,当我将
模板路径
替换为普通字符串时,如下所示:

(define render-template
  (make-keyword-procedure
    (lambda
      (keywords keyword-args [content "<p>no content!</p>"] [template-path "template/base.html"])
      (let
        ([content content])
        (include-template "templates/base.html")))))
(定义渲染模板
(制作关键字程序)
(兰姆达)
(关键字args[content”无内容!

“][模板路径“template/base.html”]) (让 ([内容]) (包括模板“templates/base.html”;))
错误不会发生。Racket似乎想确保
包含模板有一个有效的路径。但我希望这是程序的一个值。否则,我无法编写执行此任务的过程

我还希望提供给过程的关键字的值对模板可见。我不确定,如果这是自动发生的,或者我是否需要在
include template
调用周围放置某种类型的
let
,因为我还不能让代码运行,以测试这一点

如何编写这样的程序

作为理想程序的一个示例,我希望:

  • Jinja2的
    渲染模板
我可以提供我想要的任何关键字参数,并呈现我想要呈现的任何模板。我也不太明白,为什么像
“rm-rf/”
这样的东西会损坏任何东西。在我看来,Web服务器应该简单地检查是否存在具有该名称的文件。显然它不存在,所以抛出一个错误。这将如何导致任何不必要的损害?因此,我不理解将模板路径限制为字符串的原因(解决方法除外)。但是,对于一个SO问题来说,这可能太多了,应该放到另一个关于“为什么”的问题中。

如果要应用变量路径参数,可以将渲染过程定义为:

(define (dynamic-include-template path)
  (eval #`(include-template #,path)))
该过程接受任何模板路径作为参数,并包含该模板。例如,
(动态包含模板“static.html”)
将呈现
static.html

这可以扩展为接受任意数量的关键字,并使它们在呈现的模板中可用,如下所示:

(define render-template
  (make-keyword-procedure
   (lambda (kws kw-args
                [path "templates/base.html"]
                [content "<p>no content!</p>"])
     (for ([i kws]
           [j kw-args])
       (namespace-set-variable-value!
        (string->symbol (keyword->string i)) j))
     (namespace-set-variable-value! 'content content)
     (dynamic-include-template path))))
然后在
模板/homebook overview.html
中,您将拥有:

...
@dates
...
<>请注意,当使用<代码> EVA时,请考虑以下相关阅读:


文档中标题为“解决您的问题”的部分。对于此解决方案,我只有两个问题。一个是我遇到的错误,因为函数突然查看路径:/home/xiaolong/development/Racket/blog2/htdocs/templates/base.html
,自然找不到该文件,因为在我的整个项目中没有
htdocs
文件夹。这很奇怪,因为这个答案根本不包含
htdocs
,所以我不知道它突然从哪里来。另一个问题是,我不能为这个过程提供任意的关键字参数。当我使用
make keyword procedure
但仍然必须使用
let
时,我如何知道任意关键字参数的名称?也许我必须使用此aproach设置默认路径?对于您的第一个问题,我无法在本地复制它。我创建了一个
templates
目录,在该目录下存储了一些内容的
static.html
,然后尝试了
(呈现模板“templates/static.html”)
(在包含
templates
文件夹的同一目录中定义了
呈现模板
,它可以正常工作,因此,创建问题可能存在于代码的其他地方。对于第二个问题,一个选项是列出lambda中所有可能的关键字,然后为每个可能的关键字创建一个
[标识符#,关键字]
绑定(类似于上面使用的
内容
日期
关键字)。没有使用的关键字没有任何效果,只要它们不在呈现的模板中。嗯,我想你可以尝试重新构造。另外,
htdocs
似乎是默认web根路径下的目录。正如建议的那样,“除了服务器根路径下的“htdocs”目录之外,还可以为文件路径提供额外的文件路径。这些路径将首先按照它们在列表中出现的顺序进行检查。”。
(render-template "templates/homework-overview.html"
                 #:dates (sort (get-all-homework-dates) string<?))
...
@dates
...