{-# LANGUAGE QuasiQuotes #-}
module Main where
import Control.Monad.Trans(MonadIO(liftIO))
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Char8 as L
import qualified Data.Map as M
import qualified Data.Text.Lazy.Encoding as T
import Text.Hamlet
import Text.Hamlet.Monad (hamletToText)
import Data.Text (pack)
import Happstack.Server
data Person = Person
{ name :: IO HtmlContent -- maybe it requires a database lookup
, age :: HtmlContent
, page :: PersonUrls
, isMarried :: Bool
, children :: [HtmlContent]
}
data PersonUrls = Homepage | PersonPage String
renderUrls :: PersonUrls -> String
renderUrls Homepage = "/"
renderUrls (PersonPage name) = '/' : name
footer :: Monad m => a -> Hamlet url m ()
footer = [$hamlet|
#footer Thank you, come again
|]
template :: Person -> Hamlet PersonUrls IO ()
template = [$hamlet|
!!!
%html
%head
%title Hamlet Demo
%body
%h1 Information on $*name$
%p $*name$ is $age$ years old.
%h2
$if isMarried
Married
$else
Not married
%ul
$forall children child
%li $child$
%p
%a!href=@page@ See the page.
^footer^
|]
person :: Person
person = Person
{ name = return $ Unencoded $ pack "Michael"
, age = Unencoded $ pack "twenty five & a half"
, page = PersonPage "michael"
, isMarried = True
, children = [ Unencoded $ pack "Adam"
, Unencoded $ pack "Ben"
, Unencoded $ pack "Chris"
]
}
-- happstack changes
main :: IO ()
main = simpleHTTP nullConf $ liftIO $ hamletToResponse renderUrls $ template person
hamletToResponse :: (Monad m) => (url -> String) -> Hamlet url m () -> m Response
hamletToResponse showFn hamlet =
do msg <- hamletToText showFn hamlet
return $ toResponse_ (B.pack "text/html; charset=UTF-8") (T.encodeUtf8 msg)
toResponse_ :: B.ByteString -> L.ByteString -> Response
toResponse_ contentType message =
let res = Response 200 M.empty nullRsFlags message Nothing
in setHeaderBS (B.pack "Content-Type") contentType res