Snap-Heist:为什么我的模板没有渲染?

时间:2013-12-31 22:54:40

标签: haskell haskell-snap-framework heist

我正在尝试使用Snap和Heist渲染模板。

我确定我的处理函数被正确调用(如果我用undefined替换处理函数的内容,它会按预期失败。Debug.Trace.trace也按预期工作。)

此处理函数由一行组成:render "template"。但由于某些原因,我收到了No handler accepted <url>错误,而不是template not found或类似错误。

我认为这里的问题是我将模板放在错误的目录中,但是无法知道在哪里搜索模板。所以我的问题是:

  1. 此错误消息是否具有误导性?应该是template not found: template.tpl
  2. 之类的东西
  3. 我在哪里可以知道搜索哪些目录的模板?
  4. 我认为snap init创建的快照应用程序是个问题。我只对它做了一些修改:

    • 我在App记录中添加了一个字段:_myapp :: Snaplet Myapp
    • app初始化函数中,我添加了n <- embedSnaplet "myapp" myapp myappInit,然后将n传递给记录。
    • 我创建了新文件src/Myapp.hs

    以下是Myapp.hs中的相关部分:

    myappInit = do
        ...
        h <- nestSnaplet "" heist $ hesitInit "myapp_templates"
        addRoutes routes
        ...
    
    routes = [ ("/submit", submitHandler) ]
    
    submitHandler = trace "rendering submit" $ render "submit"
    

    但是出于某种原因,即使我在转到rendering submit时看到http://0.0.0.0:8000/myapp/submit打印到控制台,我得到No handler accepted "/hsnews/submit"消息作为HTTP响应(而不是渲染模板)。我在submit.tpl中有_submit.tplsnaplets/heist/myapp_templates

2 个答案:

答案 0 :(得分:2)

1:我同意渲染模板应该有两种不同类型的错误。可悲的是,据我所知,事实并非如此。

2。:简答:使用的目录写在你的heistInit函数中。 e.g。

h <- nestSnaplet "" heist $ heistInit "templates"

表示可以访问“snaplets / heist / templates / ”中的所有文件,包括子目录。


答案很长:

heist目录结构的默认行为如下: 可以从snaplet / heist / templates /目录访问所有.tpl文件。含义

addRoutes [("template", render "template")]

将访问该文件

snaplets/heist/templates/template.tpl

可在网址

访问
http://localhost:8000/template

您也可以使用子目录,例如:

addRoutes [("users", render "users/index")]
path = snaplets/heist/templates/users/index.tpl
url  = http://localhost:8000/users

要修改此行为,您可以调整heistInit函数。

假设您希望目录路径为“snaplets / heist /”而不是“snaplets / heist / templates /”

只需更改:

h <- nestSnaplet "" heist $ heistInit "templates"

到此:

h <- nestSnaplet "" heist $ heistInit ""

heistInit的参数是tpl文件的目录位置。 所以你可以根据自己的意愿调整它。

我希望这能回答你的问题。

答案 1 :(得分:1)

阁楼的回答非常好,但没有解决我的问题。这是因为nestSnapletembedSnaplet之间存在差异。

我认为embedSnaplet的文件没有提到这种差异:

  

运行另一个snaplet的初始值设定项并返回初始化的Snaplet值。这和nestSnaplet之间的区别是第三个参数中的第一个类型参数。 “v1 v1”使子snaplet认为它是顶级的,这意味着它将无法使用snaplet树中包含的snaplet提供的功能。这强烈隔离了子snaplet,并允许您消除b类型变量。嵌入式snaplet仍然可以从其他snaplet获取功能,但前提是它嵌套或嵌入snaplet本身。

但也存在这种差异,在embedSnaplet中,子snaplet在snaplets/embeddedSnapletName中有一个新的根目录,嵌入式snaplet的所有子snaplet都将以snaplets/embeddedSnapletName文件夹作为root。< / p>

所以我必须将templates文件夹放到snaplets/myapp/templates并解决了它。