【问题标题】:Yesod - include widget directly in templateYesod - 直接在模板中包含小部件
【发布时间】:2017-08-26 13:24:17
【问题描述】:

我有一个脚手架 Yesod 应用程序并创建了一个简单的小部件,看起来像这样,位于单独的模块中:

module Widget.Header where

import Prelude
import Yesod

twitterWidget :: MonadWidget m => String -> m ()
twitterWidget twitteruser = do
   toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
                            <script async src="//platform.twitter.com/widgets.js" charset="utf-8">
                       |])

我已将此模块包含到 .cabal 文件中,我可以将其加载到处理程序中,一切正常。

twitterUsername :: String
twitterUsername = "someusername"

getHomeR :: Handler Html
getHomeR = do
    (formWidget, formEnctype) <- generateFormPost sampleForm
    let submission = Nothing :: Maybe FileForm
        handlerName = "getHomeR" :: Text
    defaultLayout $ do
        let (commentFormId, commentTextareaId, commentListId) = commentIds
        aDomId <- newIdent
        setTitle "Some title"
        twitterWidget twitterUsername 
        $(widgetFile "homepage")

所以我想做的是直接在另一个模板中使用它,但是当我尝试这样做时:

^{twitterWidget twitterUsername}

我明白了

• Ambiguous type variable ‘m1’ arising from a use of ‘toWidget’
      prevents the constraint ‘(ToWidget App (m1 ()))’ from being solved.
      Probable fix: use a type annotation to specify what ‘m1’ should be.
      These potential instances exist:
        instance (site' ~ site, IO ~ m, a ~ ()) =>
                 ToWidget site' (WidgetT site m a)
          -- Defined in ‘Yesod.Core.Widget’
        ...plus one instance involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the second argument of ‘(GHC.Base..)’, namely ‘toWidget’
      In the expression: asWidgetT GHC.Base.. toWidget
      In a stmt of a 'do' block:
        (asWidgetT GHC.Base.. toWidget) (twitterWidget twitterUsername)

所以我的问题是,在网站各处的模板中加载多个小部件以服务于不同目的的正确方法是什么?

【问题讨论】:

  • 你能提供你的模板的内容吗?
  • 此页面的模板在标题小部件和主页上分开。 Header 小部件加载在 Foundation.hs 中的每个页面上,主页模板仅包含 html,所以我猜它没有用。

标签: haskell yesod


【解决方案1】:

改变你的

module Widget.Header where

import Prelude
import Yesod

twitterWidget :: MonadWidget m => String -> m ()
twitterWidget twitteruser = do
   toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
                        <script async src="//platform.twitter.com/widgets.js" charset="utf-8">
                   |])

类似于

module Widget.Header where

import Import

twitterWidget :: Yesod site => String -> WidgetT site IO ()
twitterWidget twitteruser = do
   toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
                        <script async src="//platform.twitter.com/widgets.js" charset="utf-8">
                   |])

这样m 肯定会变成IO 而Haskell 不必弄清楚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2015-01-23
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多