haskellblaze-html

how to get html from blaze -- print to file


I am working through the blaze-html tutorial. I just want a simple Hello World page.

{-# LANGUAGE OverloadedStrings #-}

import Control.Monad (forM_)
import Text.Blaze.Html5
import Text.Blaze.Html5.Attributes
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A

import Text.Blaze.Html.Renderer.Text

notes :: Html

notes = docTypeHtml $ do
    H.head $ do
        H.title "John´ s Page"
    body $ do
        p "Hello World!"

Where is it? How do I get my HTML? Can I just print it to the terminal or a file? That would be a great start.

<html>
<head><title>John's Page</title></head>
<body><p>Hello World!</p></body>
</html>

And are all the import statements really necessary? I just want it to work.


I tried printing using the renderHTML function but I just get an error message:

main = (renderHtml notes) >>=   putStrLn 
notes.hs:21:9:
    Couldn't match expected type `IO String'
                with actual type `Data.Text.Internal.Lazy.Text'
    In the return type of a call of `renderHtml'
    In the first argument of `(>>=)', namely `(renderHtml notes)'
    In the expression: (renderHtml notes) >>= putStrLn

Solution

  • The result of "renderHtml" is not wrapped in a monad so you don't need to use >>=

    Just print out the result:

    main = putStrLn $ show $ renderHtml notes
    

    The result is:

       "<!DOCTYPE HTML>\n<html><head><title>John&#39; s
       Page</title></head><body><p>Hello World!</p></body></html>"
    

    Generally speaking, the place to start with errors like this is to load the file into GHCI and see what the types are. Here is the session I'd use for this issue:

    *Main> :t notes
    notes :: Html
    *Main> :t renderHtml notes
    renderHtml notes :: Data.Text.Internal.Lazy.Text
    

    You can see that the output of renderHtml notes is just an instance of Text. Text has a Show instance so we can just call "putStrLn $ show $ renderHtml notes" to get the desired output.

    However, it is usually better to use the Data.Text.[Lazy.]IO package to perform IO when using Text. Note the import for "TIO" and the last line in the code below:

    {-# LANGUAGE OverloadedStrings #-}
    
    import Control.Monad (forM_)
    import Text.Blaze.Html5
    import Text.Blaze.Html5.Attributes
    import qualified Text.Blaze.Html5 as H
    import qualified Text.Blaze.Html5.Attributes as A
    
    import Text.Blaze.Html.Renderer.Text
    import qualified Data.Text.Lazy.IO as TIO
    
    notes :: Html
    
    notes = docTypeHtml $ do
        H.head $ do
            H.title "John' s Page"
        body $ do
            p "Hello World!"
    
    --main = putStrLn $ show $ renderHtml notes
    main = TIO.putStr $ renderHtml notes