I want to post the results of a curl command within an html page, using the yesod framework in haskell. This is the code i have so far:
{-# 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
This code launches the server with the warning
Warning: No explicit method nor default method for `Text.Blaze.toMarkup'
In the instance declaration for `ToMarkup (IO a)'
and on pointing the web browser to
http://localhost:3000
it gives "Internal Server Error" along the above warning message as an HTML page.
I'm fairly new to Haskell and Yesod... could someone help?
Your indentation is wrong for toMarkup
(it should be indented). However the types are still wrong. toMarkup
should return a Markup
instance and curlGet
dumps the output to stdout, whereas you want to capture it and re-render it.
Try something like this:
{-# 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
As an alternative to curl, you could also use the http-conduit package. Import Net.HTTP.Conduit
and you could write getHomeR
as:
getHomeR = fmap (RepHtml . toContent) . liftIO $ simpleHttp "http://www.google.com"