我是 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
,甚至将 nav 功能放在里面,但似乎没有任何效果。根据我的说法,我当前的代码应该可以编译,但我显然不明白 Yesod-Core 类型是如何工作的。whamletFile
handerToWidget
liftIO
defaultLayout
我怎样才能让它工作?更重要的是,我误解了什么概念?
编辑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
:
\ _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)