{-# LANGUAGE QuasiQuotes, ScopedTypeVariables, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-} module Happstack.Server.Hamlet ( hamletToResponse ) where 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, liftHamlet) import Happstack.Server -- |turn a 'Hamlet' template into a Happstack 'Response' hamletToResponse :: (Monad m) => (url -> String) -> -- ^ function to 'url' values in the template into their 'String' representation Hamlet url m () -> -- ^ a 'Hamlet' template m Response hamletToResponse showFn hamlet = do msg <- hamletToText showFn hamlet return $ toResponse_ (B.pack "text/html; charset=UTF-8") (T.encodeUtf8 msg) -- available as toResponseBS in happstack-server >= 0.5 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 mapHamlet :: forall a b url m. (Monad m) => (m a -> m b) -> Hamlet url m a -> Hamlet url m b mapHamlet f m = Hamlet $ \showFn seed iteratee -> f' (runHamlet m showFn seed iteratee) where f' :: m (Either seed (a, seed)) -> m (Either seed (b, seed)) f' m = do e <- m case e of (Left s) -> return (Left s) (Right (a, seed)) -> do b <- f (return a) return (Right (b, seed)) instance (ServerMonad m) => ServerMonad (Hamlet url m) where askRq = liftHamlet askRq localRq f = mapHamlet (localRq f) instance (FilterMonad r m) => FilterMonad r (Hamlet url m) where setFilter = liftHamlet . setFilter composeFilter = liftHamlet . composeFilter getFilter = mapHamlet getFilter instance (WebMonad a m) => WebMonad a (Hamlet url m) where finishWith = liftHamlet . finishWith