从Yesod提供CSS文档

时间:2014-04-02 04:11:10

标签: haskell types yesod

我刚刚开始使用Yesod并尝试从服务器提供一个小的CSS文件。

我最初写道:

getMainStyleR :: Handler HTML
getMainStyleR = [cassius|
    #main
        color: 333333
        font-family: Sans
|]

给出了以下类型错误:

 Couldn't match expected type `t0
                                  -> shakespeare-css-1.0.7.1:Text.Css.Css'
                with actual type `HandlerT HelloWorld IO Html'

我认为因为CSS不是HTML?这是对的吗?

如果是这样,如果我拿出getMainStyleR的类型声明(为了看看Haskell的推断)我得到了

Couldn't match expected type `HandlerT site0 IO res0'
                with actual type `t0 -> shakespeare-css-1.0.7.1:Text.Css.Css'

所以我假设处理程序需要给HTML,所以如果我想生成CSS怎么办?

我猜到了:

getMainStyleR :: Handler Css
getMainStyleR = [cassius|
    #main
        color: 333333
        font-family: Sans
|]

但这只是说:

Not in scope: type constructor or class `Css'

是否有返回CSS块的类型? (这似乎是你在某些时候需要的东西)

更新:

我试过@Michael Snoyman的建议如下。我现在收到此错误:

No instance for (ToTypedContent Css)
      arising from a use of `yesodRunner'
    Possible fix: add an instance declaration for (ToTypedContent Css)
    In the expression: yesodRunner getMainStyleR
    In the expression:
      ((Data.Text.Encoding.encodeUtf8 . Data.Text.pack) "GET", 
       yesodRunner getMainStyleR)
    In the first argument of `containers-0.5.0.0:Data.Map.Base.fromList', namely
      `[((Data.Text.Encoding.encodeUtf8 . Data.Text.pack) "GET", 
         yesodRunner getMainStyleR)]'

1 个答案:

答案 0 :(得分:4)

首先回答最简单的部分:您需要导入Css数据类型才能使用它。使用Hoogle,您可以看到它可以从Text.LuciusText.Cassius模块中获得。因此,您需要在导入语句中添加import Text.Lucius (Css)等。

下一个问题是cassius引用的实际类型。了解这一点的最佳地点是Yesod book's chapter on Shakespeare。重要的是cassius正在生成函数,而不是普通的Css值。该函数的参数是一个URL呈现函数。为此,您需要使用getUrlRenderParams

最后一个问题是你需要在Handler monad中返回结果,这需要使用return来包装纯值。

将它们放在一起,你的处理函数看起来像:

getMainStyleR = do
    render <- getUrlRenderParams
    return $ [cassius|...|] render