【问题标题】:Snap: compiled splice dependent on runtime decision and URL variableSnap:编译的拼接依赖于运行时决策和 URL 变量
【发布时间】:2013-10-30 02:26:30
【问题描述】:

我有一种情况,我必须构建已编译的接头并将数据输入其中,这取决于 URL 变量。我很难解决问题。

所以有一个简单的文件名列表需要在表格中呈现。简单的。 文件属于一个组或类别,因此您可以列出所有文件或与特定类别相关的文件。我使用此功能提取数据:

getFilesList :: Maybe ByteString -> AppHandler [Document]
getFilesList cat = do
  let selection = maybe [] (\c -> ["category" =: T.decodeUtf8 c]) cat
  r <- eitherWithDB $ rest =<< find (select selection "files") {project = ["blob" =: 0]}
  return $ either (const []) id r

如果它得到 Nothing 它会拉出整个列表如果它得到 Just 类别它会拉出属于该类别的文件。到目前为止很容易。

我从处理程序中调用上述函数,以便我可以将参数输入其中。

listFiles :: AppHandler [Document]
listFiles = do
  cat <- getParam "cat"
  let r = maybe Nothing (\c -> if c == "all" then Nothing else Just c) cat
  render "files/list-files"
  getFilesList r

如果我在 URL 上得到“全部”或没有 - 我得到完整列表。除此之外的任何东西 - 我得到一个类别过滤列表。

URL 根目录如下所示

("/files/:cat",           method GET    listFiles)

但是现在我有一个问题,因为“方法”函数将只接受 Handler App App() 签名。我的处理程序返回要馈送到接头的数据。

我这样构造我的接头:

listFilesS :: Splices (Splice (Handler App App))
listFilesS = "files" ## files
  where
    files = manyWithSplices runChildren file $ lift listFiles -- Feed data here
    file = do
      "file-name"     ## (pureSplice . textSplice $ at "name")
      "file-oid"      ## (pureSplice . textSplice $ id)
      "file-date"     ## (pureSplice . textSplice $ dateFromDoc)
      "file-size"     ## (pureSplice . textSplice $ fsize)
      "file-type"     ## (pureSplice . textSplice $ at "type")
      "file-auth"     ## (pureSplice . textSplice $ const "admin")
      "file-link"     ## (pureSplice . textSplice $ flink)
      "file-category" ## (pureSplice . textSplice $ at "category")
      where id = T.pack . show . valueAt "_id"
        fsize = T.pack . show . round . (flip (/) 1024) . (at "size")
        flink = T.append "/files/" . id

我找不到解决办法。可能只是错过了一些愚蠢的东西。 任何想法我做错了什么?

无论如何,我的处理函数看起来不正确,因为我先渲染模板然后提取数据。如果我修复了处理程序,那么我将无法根据 URL 参数提供数据。

困惑。

【问题讨论】:

    标签: haskell haskell-snap-framework heist


    【解决方案1】:

    首先,如果listFiles 只是返回[Document],那么你就不想调用render "files/list-files"。因此,首要任务是完全消除这条线。你可能想知道为什么。这将我们带到第二点。您的路线应如下所示:

    ("/files/:cat", method GET $ render "files/list-files")
    

    您的路线是渲染模板的结果。抢劫路线几乎总是如此。有时您可能想显式调用render。其他时候你可能只使用heistServe自动给你的路线。

    如果没有看到更多Document API 的代码,我真的无法评论listFilesS,但它看起来很合理。假设它工作正常,您只需为您的应用程序绑定该拼接,如下所示:

    addConfig heist $ mempty { hcCompiledSplices = listFilesS }
    

    然后只需使用“文件/列表文件”模板中的文件标签。

    【讨论】:

    • 谢谢。我确实绑定了接头,这不是问题。问题是我没有意识到 HTTP 请求可用于已编译的拼接。这是导致问题的我的理解漏洞。所以是的,只需要移除渲染并将处理程序传递给拼接。大多数误解是由于逻辑倒置和编译拼接工作方式的怪异造成的。
    • 是的,我记得当我第一次意识到处理程序 monad 在拼接中可用时。这是一个很大的顿悟!
    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    相关资源
    最近更新 更多