Skip to content

Instantly share code, notes, and snippets.

@mightybyte
Created December 23, 2010 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mightybyte/752392 to your computer and use it in GitHub Desktop.
Save mightybyte/752392 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
-- | This module contains convenience functions for helping render
-- Heist templates from Snap.
module Snap.Heist where
------------------------------------------------------------------------------
import Control.Applicative
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B
import Snap.Types
import Snap.Util.FileServe
import Text.Templating.Heist
------------------------------------------------------------------------------
-- | This is a convenience function. It calls 'render' with the
-- content type set to @text/html; charset=utf-8@.
renderHtml :: (MonadSnap m) => TemplateState m -> ByteString -> m ()
renderHtml = renderHtml' id
--renderHtml' :: (Monad m, MonadSnap n) => TemplateState m -> ByteString -> m ()
renderHtml' :: (Monad m, MonadSnap n)
=> (forall a. m a -> n a)
-> TemplateState m -> ByteString -> n ()
renderHtml' = render' "text/html; charset=utf-8"
------------------------------------------------------------------------------
-- | Renders a template with the provided content type. If the
-- template cannot be loaded, 'pass' is called and the next handler is tried.
render :: (MonadSnap m)
=> ByteString -- ^ the content type to include in the response
-> TemplateState m -- ^ the TemplateState that contains the template
-> ByteString -- ^ the name of the template
-> m ()
render contentType = render' contentType id
------------------------------------------------------------------------------
-- | Renders a template with the provided content type. If the
-- template cannot be loaded, 'pass' is called and the next handler is tried.
render' :: (Monad m, MonadSnap n)
=> ByteString -- ^ the content type to include in the response
-> (forall a. m a -> n a)
-> TemplateState m -- ^ the TemplateState that contains the template
-> ByteString -- ^ the name of the template
-> n ()
render' contentType f ts template = do
bytes <- f $ renderTemplate ts template
flip (maybe pass) bytes $ \x -> do
modifyResponse $ setContentType contentType
. setContentLength (fromIntegral $ B.length x)
writeBS x
------------------------------------------------------------------------------
-- | Handles the rendering of any template in TemplateState.
handleAllTemplates :: (MonadSnap m)
=> TemplateState m -> m ()
handleAllTemplates ts =
ifTop (renderHtml ts "index") <|>
(renderHtml ts . B.pack =<< getSafePath)
------------------------------------------------------------------------------
-- | Handles the rendering of any template in TemplateState.
handleAllTemplates' :: (Monad m, MonadSnap n)
=> (forall a. m a -> n a)
-> TemplateState m -> n ()
handleAllTemplates' f ts =
ifTop (renderHtml' f ts "index") <|>
(renderHtml' f ts . B.pack =<< getSafePath)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment