【问题标题】:Snap-Heist: why my template is not rendered?Snap-Heist:为什么我的模板没有被渲染?
【发布时间】:2015-12-14 14:13:57
【问题描述】:

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

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

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

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

  1. 此错误消息是否具有误导性?它应该类似于template not found: template.tpl
  2. 我在哪里可以知道在哪些目录中搜索了模板?

我认为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"

但由于某种原因,即使我在转到http://0.0.0.0:8000/myapp/submit 时看到rendering submit 打印到控制台,我还是收到No handler accepted "/hsnews/submit" 消息作为HTTP 响应(而不是呈现的模板)。我在snaplets/heist/myapp_templates 中有submit.tpl_submit.tpl

【问题讨论】:

    标签: haskell haskell-snap-framework heist


    【解决方案1】:

    1.:我同意渲染模板应该有两种不同类型的错误。遗憾的是,据我所知,情况并非如此。

    2.: 简短回答: 使用的目录写在你的 heistInit 函数中。例如

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

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


    长答案:

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

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

    将访问该文件

    snaplets/heist/templates/template.tpl
    

    可以通过url访问

    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 文件的目录位置。 所以你可以随心所欲地调整它。

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

    【讨论】:

    • 我只想补充一点,由于 snap 的工作方式,在这种情况下我们无法改进错误消息。 Snap 的路由非常通用,所以我们的错误信息必须是通用的。如果您想要更好的错误消息,您应该以一种允许您自己设置更好的错误消息的方式来构建您的路由。
    【解决方案2】:

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

    我认为embedSnaplet 的文档没有提到这个区别:

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

    但也有这个区别,在embedSnaplet中,子snaplet在snaplets/embeddedSnapletName中有一个新的根目录,嵌入snaplet的所有子snaplet都将使用snaplets/embeddedSnapletName文件夹作为根目录。

    所以我不得不将我的templates 文件夹放到snaplets/myapp/templates 中,这样就解决了。

    【讨论】:

      猜你喜欢
      • 2011-06-21
      • 2013-07-10
      • 1970-01-01
      • 2016-04-23
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      相关资源
      最近更新 更多