如何使用yesod在html页面上显示curl结果?

时间:2013-03-12 13:49:31

标签: haskell curl yesod

我想在html页面中发布curl命令的结果, 在haskell中使用yesod框架。 这是我到目前为止的代码:

{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses,
         TemplateHaskell, OverloadedStrings #-}
import Yesod
import Network.Curl
import Text.Blaze hiding (toMarkup)

data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]

url = "http://www.google.com/"
opts = [CurlFollowLocation True]

res=withCurlDo $ do
            curlGet url opts
            return ()

instance ToMarkup (IO a) where
toMarkup a = a

instance Yesod HelloWorld

getHomeR :: Handler RepHtml
getHomeR = defaultLayout [whamlet|#{toMarkup res}|]

main :: IO ()
main = warpDebug 3000 HelloWorld

此代码使用警告

启动服务器
Warning: No explicit method nor default method for `Text.Blaze.toMarkup'
In the instance declaration for `ToMarkup (IO a)'

并指向Web浏览器

http://localhost:3000

它将上述警告消息中的“内部服务器错误”作为HTML页面提供。

我对Haskell和Yesod相当新闻......有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

toMarkup的缩进是错误的(它应该缩进)。但是类型仍然是错误的。 toMarkup应该返回一个Markup实例,curlGet将输出转储到stdout,而你想捕获它并重新渲染它。

尝试这样的事情:

{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings #-}
import Yesod
import Network.Curl

data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
      / HomeR GET
    |]

url = "http://www.google.com/"
opts = [CurlFollowLocation True]

instance Yesod HelloWorld

getHomeR = do
    (code, res) <- liftIO $ curlGetString url opts        
    -- This doesn't work since Yesod HTML-escapes the content in the template
    -- defaultLayout [whamlet|#{res}|]
    return $ RepHtml $ toContent res

main :: IO ()
main = warpDebug 3000 HelloWorld

作为curl的替代方法,您还可以使用http-conduit package。导入Net.HTTP.Conduit,您可以将getHomeR写为:

getHomeR = fmap (RepHtml . toContent) . liftIO $ simpleHttp "http://www.google.com"