【发布时间】:2016-07-11 20:27:11
【问题描述】:
我是 Yesod 的新手,似乎对小部件、处理程序、Hamlets、WHamlets 以及你有什么完全迷失了!这是我正在尝试做的事情:
- 我网站上的每个页面都需要有一个导航栏,这让我相信实现它的正确位置应该是
defaultLayout - 现在,此导航栏需要显示一些从 IO 操作中获得的信息(更具体地说,它是一个提供此数据的 RPC 调用)。
因此,我尝试在Foundation.hs 中编写以下函数(代码布局是基本的yesod-sqlite 脚手架模板):
nav = do
globalStat <- handlerToWidget $ A2.getGlobalStat NWT.ariaRPCUrl
$(whamletFile "templates/navbar.hamlet)
A2.getGlobalStat :: IO GlobalStatResponse
template/navbar.hamlet 是这样的:
<nav .navbar .navbar-default>
<div .container-fluid>
<p .navbar-right .navbar-text>
<span>
#{A2.glDownloadSpeed globalStat}
<i .glyphicon .glyphicon-arrow-down>
<span>
#{A2.glUploadSpeed globalStat}
<i .glyphicon .glyphicon-arrow-up>
<span .label .label-success>
On-the-watch
default-layout-wrapper.hamlet 是这样的:
<!-- SNIP -->
<body>
<div class="container">
<header>
^{nav}
<div id="main" role="main">
^{pageBody pc}
<!-- SNIP -->
defaultLayout 是这样的:
defaultLayout widget = do
master <- getYesod
mmsg <- getMessage
pc <- widgetToPageContent $ do
addStylesheet $ StaticR css_bootstrap_css
$(widgetFile "default-layout")
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
但是,代码拒绝编译一个又一个类型错误。我尝试了很多hametFile、whamletFile、handerToWidget、liftIO 的组合,甚至将导航功能 inside defaultLayout,但似乎没有任何效果。据我说,我当前的代码应该编译,但我显然不明白 Yesod-Core 类型是如何工作的。
如何让它工作?更重要的是,我误解了什么概念?
编辑 1:
已尝试将nav 函数修改为以下内容:
nav :: Handler Html
nav = do
globalStat <- liftIO $ A2.getGlobalStat NWT.ariaRPCUrl
$(hamletFile "templates/navbar.hamlet")
但是,它会导致defaultLayout 与withUrlRenderer 的行出现以下类型不匹配:
Couldn't match type ‘HandlerT App IO Html’
with ‘Text.Hamlet.Render (Route App) -> Html’
Expected type: HtmlUrl (Route App)
Actual type: Handler Html
In the first argument of ‘Text.Hamlet.asHtmlUrl’, namely ‘nav’
In a stmt of a 'do' block: Text.Hamlet.asHtmlUrl nav _render_a2ZY0 (intero)
编辑 2:
尝试将nav 的类型签名更改为:
nav :: Widget
nav = do
globalStat <- liftIO $ A2.getGlobalStat NWT.ariaRPCUrl
$(hamletFile "templates/navbar.hamlet")
但它会在同一行中导致新的类型不匹配:
Couldn't match type ‘WidgetT App IO ()’
with ‘Text.Hamlet.Render (Route App) -> Html’
Expected type: HtmlUrl (Route App)
Actual type: Widget
In the first argument of ‘Text.Hamlet.asHtmlUrl’, namely ‘nav’
In a stmt of a 'do' block: Text.Hamlet.asHtmlUrl nav _render_a350l (intero)
编辑 3:
这是来自-ddump-splices的相关sn-p:
\ _render_a28TE
-> do { asHtmlUrl (pageHead pc) _render_a28TE;
id ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "\n");
asHtmlUrl (pageBody pc) _render_a28TE;
id ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "\n");
asHtmlUrl testWidget2 _render_a28TE }
(pageHead pc)和(pageBody pc)的类型是HtmlUrl (Route App)
【问题讨论】:
-
编辑了我的问题以发布基于
liftIO方法的新代码 sn-ps。现在,问题似乎是default-layout-wrapper模板中的^{nav}用法似乎没有很好地组合。
标签: haskell yesod shakespeare-text