{-# LANGUAGE QuasiQuotes, ScopedTypeVariables, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
module Main where
import Control.Monad.Trans(MonadIO(liftIO))
import Data.Text (pack)
import Happstack.Server
import Happstack.Server.Hamlet
import Text.Hamlet
import Text.Hamlet.Monad (hamletToText, liftHamlet)
-- | type used to populate the template
data Person = Person
{ name :: IO HtmlContent -- maybe it requires a database lookup
, age :: HtmlContent
, page :: PersonUrls
, isMarried :: Bool
, children :: [HtmlContent]
}
-- | type which represents paths to different pages on the site
data PersonUrls = Homepage | PersonPage String
-- | function to turn the url type into a string
renderUrls :: PersonUrls -> String
renderUrls Homepage = "/"
renderUrls (PersonPage name) = '/' : name
-- | hamlet template which generates page footer
footer :: Monad m => Hamlet url m ()
footer = [$hamlet|
#footer Thank you, come again
|]
-- | hamlet template which generates a page
template :: Person -> Hamlet PersonUrls IO ()
template person = [$hamlet|
!!!
%html
%head
%title Hamlet Demo
%body
%h1 Information on $*name.person$
%p $*name.person$ is $age.person$ years old.
%h2
$if isMarried.person
Married
$else
Not married
%ul
$forall children.person child
%li $child$
%p
%a!href=@page.person@ See the page.
^footer^
|]
-- | some dummy content to use with the template
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"
]
}
-- | example of using 'hamletToResponse' to turn the 'Hamlet' template
-- into a 'ServerPartT IO Response'.
--
-- NOTE: we ignore the requested URL in this example for simplicity
main :: IO ()
main = simpleHTTP nullConf $ liftIO $ hamletToResponse renderUrls $ template person