2013-03-12 78 views
1

我想在html页面中发布一个curl命令的结果, 在haskell中使用yesod框架。 这是我的代码至今:如何使用yesod在html页面上显示卷曲结果?

{-# 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)' 

和指向网页浏览器

http://localhost:3000 

它给“内部服务器错误“作为HTML页面沿着上述警告消息。

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

回答

1

您的缩进在toMarkup(它应该缩进)是错误的。但是这些类型仍然是错误的。 toMarkup应该返回一个Markup实例,并且curlGet将输出转储到标准输出,而您想要捕获它并重新呈现它。

尝试这样:

{-# 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 

作为替代卷曲,你也可以使用http-conduit package。进口Net.HTTP.Conduit,你可以写getHomeR为:

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

谢谢卢克......这非常有帮助! – sudoking 2013-03-13 06:29:10