{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE NoMonomorphismRestriction  #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FunctionalDependencies     #-}
{-# LANGUAGE TypeSynonymInstances       #-}

{-|

This module implements the Heist snaplet without using type classes.  It is
provided mainly as an example of how snaplets can be written with and without
a type class for convenience.

-}
module Snap.Snaplet.HeistNoClass
  ( Heist
  , DefaultMode(..)
  , heistInit
  , heistInit'
  , heistReloader
  , setInterpreted
  , getCurHeistConfig
  , clearHeistCache

  , addTemplates
  , addTemplatesAt
  , getHeistState
  , modifyHeistState
  , modifyHeistState'
  , withHeistState
  , withHeistState'

  , gRender
  , gRenderAs
  , gHeistServe
  , gHeistServeSingle
  , chooseMode

  , addConfig
  , cRender
  , cRenderAs
  , cHeistServe
  , cHeistServeSingle

  , render
  , renderAs
  , heistServe
  , heistServeSingle
  , heistLocal
  , withSplices
  , renderWithSplices
  , heistLocal'
  , withSplices'
  , renderWithSplices'

  , SnapletHeist
  , SnapletISplice
  , SnapletCSplice
  ) where

import           Prelude hiding ((.), id)
import           Control.Applicative
import           Control.Category
import           Control.Lens
import           Control.Monad.Reader
import           Control.Monad.State
import           Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import           Data.DList (DList)
import qualified Data.HashMap.Strict as Map
import           Data.IORef
import           Data.Maybe
import qualified Data.Text as T
import           Data.Text.Encoding
import           System.FilePath.Posix
import           Heist
import qualified Heist.Compiled as C
import qualified Heist.Interpreted as I
import           Heist.Splices.Cache

#if !MIN_VERSION_base(4,8,0)
import           Data.Monoid
#endif

import           Snap.Snaplet
import           Snap.Snaplet.Heist.Internal
import           Snap.Core
import           Snap.Util.FileServe


------------------------------------------------------------------------------
changeState :: (HeistState (Handler a a) -> HeistState (Handler a a))
            -> Heist a
            -> Heist a
changeState :: forall a.
(HeistState (Handler a a) -> HeistState (Handler a a))
-> Heist a -> Heist a
changeState HeistState (Handler a a) -> HeistState (Handler a a)
_ (Configuring IORef (HeistConfig (Handler a a), DefaultMode)
_)  =
    forall a. HasCallStack => [Char] -> a
error [Char]
"changeState: HeistState has not been initialized"
changeState HeistState (Handler a a) -> HeistState (Handler a a)
f (Running HeistConfig (Handler a a)
hc HeistState (Handler a a)
hs CacheTagState
cts DefaultMode
dm) = forall b.
HeistConfig (Handler b b)
-> HeistState (Handler b b)
-> CacheTagState
-> DefaultMode
-> Heist b
Running HeistConfig (Handler a a)
hc (HeistState (Handler a a) -> HeistState (Handler a a)
f HeistState (Handler a a)
hs) CacheTagState
cts DefaultMode
dm


------------------------------------------------------------------------------
-- | Clears data stored by the cache tag.  The cache tag automatically reloads
-- its data when the specified TTL expires, but sometimes you may want to
-- trigger a manual reload.  This function lets you do that.
clearHeistCache :: Heist b -> IO ()
clearHeistCache :: forall b. Heist b -> IO ()
clearHeistCache = CacheTagState -> IO ()
clearCacheTagState forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall b. Heist b -> CacheTagState
_heistCTS


                         -----------------------------
                         -- SnapletSplice functions --
                         -----------------------------

------------------------------------------------------------------------------
-- | This instance is here because we don't want the heist package to depend
-- on anything from snap packages.
instance MonadSnap m => MonadSnap (HeistT n m) where
    liftSnap :: forall a. Snap a -> HeistT n m a
liftSnap = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *) a. MonadSnap m => Snap a -> m a
liftSnap


type SnapletHeist b m a = HeistT (Handler b b) m a
type SnapletCSplice b = SnapletHeist b IO (DList (Chunk (Handler b b)))
type SnapletISplice b = SnapletHeist b (Handler b b) Template


                          ---------------------------
                          -- Initializer functions --
                          ---------------------------


------------------------------------------------------------------------------
-- | The 'Initializer' for 'Heist'. This function is a convenience wrapper
-- around `heistInit'` that uses defaultHeistState and sets up routes for all
-- the templates.  It sets up a \"heistReload\" route that reloads the heist
-- templates when you request it from localhost.
heistInit :: FilePath
              -- ^ Path to templates
          -> SnapletInit b (Heist b)
heistInit :: forall b. [Char] -> SnapletInit b (Heist b)
heistInit = forall b.
Handler b (Heist b) () -> [Char] -> SnapletInit b (Heist b)
gHeistInit forall b. Handler b (Heist b) ()
heistServe


------------------------------------------------------------------------------
-- | A lower level 'Initializer' for 'Heist'.  This initializer requires you
-- to specify the initial HeistConfig.  It also does not add any routes for
-- templates, allowing you complete control over which templates get routed.
heistInit' :: FilePath
               -- ^ Path to templates
           -> HeistConfig (Handler b b)
               -- ^ Initial HeistConfig
           -> SnapletInit b (Heist b)
heistInit' :: forall b.
[Char] -> HeistConfig (Handler b b) -> SnapletInit b (Heist b)
heistInit' [Char]
templateDir HeistConfig (Handler b b)
initialConfig =
    forall b v.
Text
-> Text
-> Maybe (IO [Char])
-> Initializer b v v
-> SnapletInit b v
makeSnaplet Text
"heist" Text
"" forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall b.
[Char]
-> HeistConfig (Handler b b) -> Initializer b (Heist b) (Heist b)
heistInitWorker [Char]
templateDir HeistConfig (Handler b b)
initialConfig


------------------------------------------------------------------------------
-- | Sets the snaplet to default to interpreted mode.  Initially, the
-- initializer sets the value to compiled mode.  This function allows you to
-- override that setting.  Note that this is just a default.  It only has an
-- effect if you use one of the generic functions: 'gRender', 'gRenderAs',
-- 'gHeistServe', or 'gHeistServeSingle'.  If you call the non-generic
-- versions directly, then this value will not be checked and you will get the
-- mode implemented by the function you called.
setInterpreted :: Snaplet (Heist b) -> Initializer b v ()
setInterpreted :: forall b v. Snaplet (Heist b) -> Initializer b v ()
setInterpreted Snaplet (Heist b)
h =
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef (forall b. Heist b -> IORef (HeistConfig (Handler b b), DefaultMode)
_heistConfig forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall s. Lens' (Snaplet s) s
snapletValue Snaplet (Heist b)
h)
        (\(HeistConfig (Handler b b)
hc,DefaultMode
_) -> ((HeistConfig (Handler b b)
hc,DefaultMode
Interpreted),()))


------------------------------------------------------------------------------
-- | Adds templates to the Heist HeistConfig.  Other snaplets should use
-- this function to add their own templates.  The templates are automatically
-- read from the templates directory in the current snaplet's filesystem root.
addTemplates :: Snaplet (Heist b)
             -> ByteString
                 -- ^ The url prefix for the template routes
             -> Initializer b (Heist b) ()
addTemplates :: forall b.
Snaplet (Heist b) -> ByteString -> Initializer b (Heist b) ()
addTemplates Snaplet (Heist b)
h ByteString
urlPrefix = do
    [Char]
snapletPath <- forall (m :: * -> * -> * -> *) b v.
(Monad (m b v), MonadSnaplet m) =>
m b v [Char]
getSnapletFilePath
    forall b.
Snaplet (Heist b)
-> ByteString -> [Char] -> Initializer b (Heist b) ()
addTemplatesAt Snaplet (Heist b)
h ByteString
urlPrefix ([Char]
snapletPath [Char] -> [Char] -> [Char]
</> [Char]
"templates")


------------------------------------------------------------------------------
-- | Adds templates to the Heist HeistConfig, and lets you specify where
-- they are found in the filesystem.  Note that the path to the template
-- directory is an absolute path.  This allows you more flexibility in where
-- your templates are located, but means that you have to explicitly call
-- getSnapletFilePath if you want your snaplet to use templates within its
-- normal directory structure.
addTemplatesAt :: Snaplet (Heist b)
               -> ByteString
                   -- ^ URL prefix for template routes
               -> FilePath
                   -- ^ Path to templates
               -> Initializer b (Heist b) ()
addTemplatesAt :: forall b.
Snaplet (Heist b)
-> ByteString -> [Char] -> Initializer b (Heist b) ()
addTemplatesAt Snaplet (Heist b)
h ByteString
urlPrefix [Char]
templateDir = do
    ByteString
rootUrl <- forall (m :: * -> * -> * -> *) b v.
(Monad (m b v), MonadSnaplet m) =>
m b v ByteString
getSnapletRootURL
    let fullPrefix :: [Char]
fullPrefix = (Text -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ ByteString -> Text
decodeUtf8 ByteString
rootUrl) [Char] -> [Char] -> [Char]
</>
                     (Text -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ ByteString -> Text
decodeUtf8 ByteString
urlPrefix)
        addPrefix :: TemplateRepo -> TemplateRepo
addPrefix = ByteString -> TemplateRepo -> TemplateRepo
addTemplatePathPrefix
                      (Text -> ByteString
encodeUtf8 forall a b. (a -> b) -> a -> b
$ [Char] -> Text
T.pack [Char]
fullPrefix)
    TemplateRepo
ts <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ ([Char] -> TemplateLocation
loadTemplates [Char]
templateDir) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                   forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. HasCallStack => [Char] -> a
error forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) forall (m :: * -> *) a. Monad m => a -> m a
return
    forall b v. Text -> Initializer b v ()
printInfo forall a b. (a -> b) -> a -> b
$ [Char] -> Text
T.pack forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"...adding"
        , (forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall k v. HashMap k v -> Int
Map.size TemplateRepo
ts)
        , [Char]
"templates from"
        , [Char]
templateDir
        , [Char]
"with route prefix"
        , [Char]
fullPrefix forall a. [a] -> [a] -> [a]
++ [Char]
"/"
        ]
    let locations :: [TemplateLocation]
locations = [forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TemplateRepo -> TemplateRepo
addPrefix forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> TemplateLocation
loadTemplates [Char]
templateDir]
        add :: (HeistConfig (Handler b b), DefaultMode)
-> ((HeistConfig (Handler b b), DefaultMode), ())
add (HeistConfig (Handler b b)
hc, DefaultMode
dm) =
          ((forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (f :: * -> *) (m :: * -> *).
Functor f =>
([TemplateLocation] -> f [TemplateLocation])
-> HeistConfig m -> f (HeistConfig m)
hcTemplateLocations (forall a. Monoid a => a -> a -> a
mappend [TemplateLocation]
locations) HeistConfig (Handler b b)
hc, DefaultMode
dm), ())
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef (forall b. Heist b -> IORef (HeistConfig (Handler b b), DefaultMode)
_heistConfig forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall s. Lens' (Snaplet s) s
snapletValue Snaplet (Heist b)
h) (HeistConfig (Handler b b), DefaultMode)
-> ((HeistConfig (Handler b b), DefaultMode), ())
add


getCurHeistConfig :: Snaplet (Heist b)
                  -> Initializer b v (HeistConfig (Handler b b))
getCurHeistConfig :: forall b v.
Snaplet (Heist b) -> Initializer b v (HeistConfig (Handler b b))
getCurHeistConfig Snaplet (Heist b)
h = case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall s. Lens' (Snaplet s) s
snapletValue Snaplet (Heist b)
h of
    Configuring IORef (HeistConfig (Handler b b), DefaultMode)
ref -> do
        (HeistConfig (Handler b b)
hc, DefaultMode
_) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef (HeistConfig (Handler b b), DefaultMode)
ref
        forall (m :: * -> *) a. Monad m => a -> m a
return HeistConfig (Handler b b)
hc
    Running HeistConfig (Handler b b)
_ HeistState (Handler b b)
_ CacheTagState
_ DefaultMode
_ ->
        forall a. HasCallStack => [Char] -> a
error [Char]
"Can't get HeistConfig after heist is initialized."


------------------------------------------------------------------------------
getHeistState :: SnapletLens (Snaplet b) (Heist b)
              -> Handler b v (HeistState (Handler b b))
getHeistState :: forall b v.
SnapletLens (Snaplet b) (Heist b)
-> Handler b v (HeistState (Handler b b))
getHeistState SnapletLens (Snaplet b) (Heist b)
heist = forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall b. Heist b -> HeistState (Handler b b)
_heistState


------------------------------------------------------------------------------
modifyHeistState' :: SnapletLens (Snaplet b) (Heist b)
                  -> (HeistState (Handler b b) -> HeistState (Handler b b))
                  -> Initializer b v ()
modifyHeistState' :: forall b v.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Initializer b v ()
modifyHeistState' SnapletLens (Snaplet b) (Heist b)
heist HeistState (Handler b b) -> HeistState (Handler b b)
f = do
    forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall v b. (v -> IO (Either Text v)) -> Initializer b v ()
addPostInitHook forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. b -> Either a b
Right forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a.
(HeistState (Handler a a) -> HeistState (Handler a a))
-> Heist a -> Heist a
changeState HeistState (Handler b b) -> HeistState (Handler b b)
f


------------------------------------------------------------------------------
modifyHeistState :: SnapletLens b (Heist b)
                 -> (HeistState (Handler b b) -> HeistState (Handler b b))
                 -> Initializer b v ()
modifyHeistState :: forall b v.
SnapletLens b (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Initializer b v ()
modifyHeistState SnapletLens b (Heist b)
heist HeistState (Handler b b) -> HeistState (Handler b b)
f = forall b v.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Initializer b v ()
modifyHeistState' (forall a b. SnapletLens a b -> SnapletLens (Snaplet a) b
subSnaplet SnapletLens b (Heist b)
heist) HeistState (Handler b b) -> HeistState (Handler b b)
f


------------------------------------------------------------------------------
withHeistState' :: SnapletLens (Snaplet b) (Heist b)
                -> (HeistState (Handler b b) -> a)
                -> Handler b v a
withHeistState' :: forall b a v.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> a) -> Handler b v a
withHeistState' SnapletLens (Snaplet b) (Heist b)
heist HeistState (Handler b b) -> a
f = do
    HeistState (Handler b b)
hs <- forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall b. Heist b -> HeistState (Handler b b)
_heistState
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ HeistState (Handler b b) -> a
f HeistState (Handler b b)
hs


------------------------------------------------------------------------------
withHeistState :: SnapletLens b (Heist b)
               -> (HeistState (Handler b b) -> a)
               -> Handler b v a
withHeistState :: forall b a v.
SnapletLens b (Heist b)
-> (HeistState (Handler b b) -> a) -> Handler b v a
withHeistState SnapletLens b (Heist b)
heist HeistState (Handler b b) -> a
f = forall b a v.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> a) -> Handler b v a
withHeistState' (forall a b. SnapletLens a b -> SnapletLens (Snaplet a) b
subSnaplet SnapletLens b (Heist b)
heist) HeistState (Handler b b) -> a
f


------------------------------------------------------------------------------
-- | Adds more HeistConfig data using mappend with whatever is currently
-- there.  This is the preferred method for adding all four kinds of splices
-- as well as new templates.
addConfig :: Snaplet (Heist b)
          -> SpliceConfig (Handler b b)
          -> Initializer b v ()
addConfig :: forall b v.
Snaplet (Heist b)
-> SpliceConfig (Handler b b) -> Initializer b v ()
addConfig Snaplet (Heist b)
h SpliceConfig (Handler b b)
sc = case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall s. Lens' (Snaplet s) s
snapletValue Snaplet (Heist b)
h of
    Configuring IORef (HeistConfig (Handler b b), DefaultMode)
ref ->
        forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef IORef (HeistConfig (Handler b b), DefaultMode)
ref (HeistConfig (Handler b b), DefaultMode)
-> ((HeistConfig (Handler b b), DefaultMode), ())
add
    Running HeistConfig (Handler b b)
_ HeistState (Handler b b)
_ CacheTagState
_ DefaultMode
_ -> do
        forall b v. Text -> Initializer b v ()
printInfo Text
"finalLoadHook called while running"
        forall a. HasCallStack => [Char] -> a
error [Char]
"this shouldn't happen"
  where
    add :: (HeistConfig (Handler b b), DefaultMode)
-> ((HeistConfig (Handler b b), DefaultMode), ())
add (HeistConfig (Handler b b)
hc, DefaultMode
dm) =
      ((forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (f :: * -> *) (m :: * -> *).
Functor f =>
(SpliceConfig m -> f (SpliceConfig m))
-> HeistConfig m -> f (HeistConfig m)
hcSpliceConfig (forall a. Monoid a => a -> a -> a
`mappend` SpliceConfig (Handler b b)
sc) HeistConfig (Handler b b)
hc, DefaultMode
dm), ())


                            -----------------------
                            -- Handler functions --
                            -----------------------

------------------------------------------------------------------------------
-- | Internal helper function for rendering.
iRenderHelper :: Maybe MIMEType
             -> ByteString
             -> Handler b (Heist b) ()
iRenderHelper :: forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
iRenderHelper Maybe ByteString
c ByteString
t = do
    (Running HeistConfig (Handler b b)
_ HeistState (Handler b b)
hs CacheTagState
_ DefaultMode
_) <- forall s (m :: * -> *). MonadState s m => m s
get
    forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall a b. (a -> b) -> a -> b
$ forall (n :: * -> *).
Monad n =>
HeistState n -> ByteString -> n (Maybe (Builder, ByteString))
I.renderTemplate HeistState (Handler b b)
hs ByteString
t forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall (m :: * -> *) a. MonadSnap m => m a
pass (Builder, ByteString) -> Handler b b ()
serve
  where
    serve :: (Builder, ByteString) -> Handler b b ()
serve (Builder
b, ByteString
mime) = do
        forall (m :: * -> *). MonadSnap m => (Response -> Response) -> m ()
modifyResponse forall a b. (a -> b) -> a -> b
$ ByteString -> Response -> Response
setContentType forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe ByteString
mime Maybe ByteString
c
        forall (m :: * -> *). MonadSnap m => Builder -> m ()
writeBuilder Builder
b


------------------------------------------------------------------------------
-- | Internal helper function for rendering.
cRenderHelper :: Maybe MIMEType
              -> ByteString
              -> Handler b (Heist b) ()
cRenderHelper :: forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
cRenderHelper Maybe ByteString
c ByteString
t = do
    (Running HeistConfig (Handler b b)
_ HeistState (Handler b b)
hs CacheTagState
_ DefaultMode
_) <- forall s (m :: * -> *). MonadState s m => m s
get
    forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall (m :: * -> *) a. MonadSnap m => m a
pass (Handler b b Builder, ByteString) -> Handler b b ()
serve forall a b. (a -> b) -> a -> b
$ forall (n :: * -> *).
Monad n =>
HeistState n -> ByteString -> Maybe (n Builder, ByteString)
C.renderTemplate HeistState (Handler b b)
hs ByteString
t
  where
    serve :: (Handler b b Builder, ByteString) -> Handler b b ()
serve (Handler b b Builder
b, ByteString
mime) = do
        forall (m :: * -> *). MonadSnap m => (Response -> Response) -> m ()
modifyResponse forall a b. (a -> b) -> a -> b
$ ByteString -> Response -> Response
setContentType forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe ByteString
mime Maybe ByteString
c
        forall (m :: * -> *). MonadSnap m => Builder -> m ()
writeBuilder forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Handler b b Builder
b


------------------------------------------------------------------------------
serveURI :: Handler b (Heist b) ByteString
serveURI :: forall b. Handler b (Heist b) ByteString
serveURI = do
    [Char]
p <- forall (m :: * -> *). MonadSnap m => m [Char]
getSafePath
    -- Allows users to prefix template filenames with an underscore to prevent
    -- the template from being served.
    if forall a. Int -> [a] -> [a]
take Int
1 [Char]
p forall a. Eq a => a -> a -> Bool
== [Char]
"_" then forall (m :: * -> *) a. MonadSnap m => m a
pass else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Char] -> ByteString
B.pack [Char]
p


------------------------------------------------------------------------------
render :: ByteString
           -- ^ Name of the template
       -> Handler b (Heist b) ()
render :: forall b. ByteString -> Handler b (Heist b) ()
render ByteString
t = forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
iRenderHelper forall a. Maybe a
Nothing ByteString
t


------------------------------------------------------------------------------
renderAs :: ByteString
             -- ^ Content type
         -> ByteString
             -- ^ Name of the template
         -> Handler b (Heist b) ()
renderAs :: forall b. ByteString -> ByteString -> Handler b (Heist b) ()
renderAs ByteString
ct ByteString
t = forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
iRenderHelper (forall a. a -> Maybe a
Just ByteString
ct) ByteString
t


------------------------------------------------------------------------------
heistServe :: Handler b (Heist b) ()
heistServe :: forall b. Handler b (Heist b) ()
heistServe =
    forall (m :: * -> *) a. MonadSnap m => m a -> m a
ifTop (forall b. ByteString -> Handler b (Heist b) ()
render ByteString
"index") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall b. ByteString -> Handler b (Heist b) ()
render forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall b. Handler b (Heist b) ByteString
serveURI)


------------------------------------------------------------------------------
heistServeSingle :: ByteString -> Handler b (Heist b) ()
heistServeSingle :: forall b. ByteString -> Handler b (Heist b) ()
heistServeSingle ByteString
t =
    forall b. ByteString -> Handler b (Heist b) ()
render ByteString
t forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. HasCallStack => [Char] -> a
error ([Char]
"Template " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show ByteString
t forall a. [a] -> [a] -> [a]
++ [Char]
" not found.")


------------------------------------------------------------------------------
cRender :: ByteString
           -- ^ Name of the template
        -> Handler b (Heist b) ()
cRender :: forall b. ByteString -> Handler b (Heist b) ()
cRender ByteString
t = forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
cRenderHelper forall a. Maybe a
Nothing ByteString
t


------------------------------------------------------------------------------
cRenderAs :: ByteString
             -- ^ Content type
          -> ByteString
             -- ^ Name of the template
          -> Handler b (Heist b) ()
cRenderAs :: forall b. ByteString -> ByteString -> Handler b (Heist b) ()
cRenderAs ByteString
ct ByteString
t = forall b. Maybe ByteString -> ByteString -> Handler b (Heist b) ()
cRenderHelper (forall a. a -> Maybe a
Just ByteString
ct) ByteString
t


------------------------------------------------------------------------------
cHeistServe :: Handler b (Heist b) ()
cHeistServe :: forall b. Handler b (Heist b) ()
cHeistServe =
    forall (m :: * -> *) a. MonadSnap m => m a -> m a
ifTop (forall b. ByteString -> Handler b (Heist b) ()
cRender ByteString
"index") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall b. ByteString -> Handler b (Heist b) ()
cRender forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall b. Handler b (Heist b) ByteString
serveURI)


------------------------------------------------------------------------------
cHeistServeSingle :: ByteString -> Handler b (Heist b) ()
cHeistServeSingle :: forall b. ByteString -> Handler b (Heist b) ()
cHeistServeSingle ByteString
t =
    forall b. ByteString -> Handler b (Heist b) ()
cRender ByteString
t forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. HasCallStack => [Char] -> a
error ([Char]
"Template " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show ByteString
t forall a. [a] -> [a] -> [a]
++ [Char]
" not found.")


------------------------------------------------------------------------------
-- | Chooses between a compiled action and an interpreted action based on the
-- configured default.
chooseMode :: MonadState (Heist b1) m
           => m b
               -- ^ A compiled action
           -> m b
               -- ^ An interpreted action
           -> m b
chooseMode :: forall b1 (m :: * -> *) b.
MonadState (Heist b1) m =>
m b -> m b -> m b
chooseMode m b
cAction m b
iAction = do
    DefaultMode
mode <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall b. Heist b -> DefaultMode
_defMode
    case DefaultMode
mode of
      DefaultMode
Compiled -> m b
cAction
      DefaultMode
Interpreted -> m b
iAction


------------------------------------------------------------------------------
-- | Like render/cRender, but chooses between the two appropriately based on
-- the default mode.
gRender :: ByteString
           -- ^ Name of the template
        -> Handler b (Heist b) ()
gRender :: forall b. ByteString -> Handler b (Heist b) ()
gRender ByteString
t = forall b1 (m :: * -> *) b.
MonadState (Heist b1) m =>
m b -> m b -> m b
chooseMode (forall b. ByteString -> Handler b (Heist b) ()
cRender ByteString
t) (forall b. ByteString -> Handler b (Heist b) ()
render ByteString
t)


------------------------------------------------------------------------------
-- | Like renderAs/cRenderAs, but chooses between the two appropriately based
-- on the default mode.
gRenderAs :: ByteString
             -- ^ Content type
          -> ByteString
             -- ^ Name of the template
          -> Handler b (Heist b) ()
gRenderAs :: forall b. ByteString -> ByteString -> Handler b (Heist b) ()
gRenderAs ByteString
ct ByteString
t = forall b1 (m :: * -> *) b.
MonadState (Heist b1) m =>
m b -> m b -> m b
chooseMode (forall b. ByteString -> ByteString -> Handler b (Heist b) ()
cRenderAs ByteString
ct ByteString
t) (forall b. ByteString -> ByteString -> Handler b (Heist b) ()
renderAs ByteString
ct ByteString
t)


------------------------------------------------------------------------------
-- | Like heistServe/cHeistServe, but chooses between the two appropriately
-- based on the default mode.
gHeistServe :: Handler b (Heist b) ()
gHeistServe :: forall b. Handler b (Heist b) ()
gHeistServe = forall b1 (m :: * -> *) b.
MonadState (Heist b1) m =>
m b -> m b -> m b
chooseMode forall b. Handler b (Heist b) ()
cHeistServe forall b. Handler b (Heist b) ()
heistServe


------------------------------------------------------------------------------
-- | Like heistServeSingle/cHeistServeSingle, but chooses between the two
-- appropriately based on the default mode.
gHeistServeSingle :: ByteString -> Handler b (Heist b) ()
gHeistServeSingle :: forall b. ByteString -> Handler b (Heist b) ()
gHeistServeSingle ByteString
t = forall b1 (m :: * -> *) b.
MonadState (Heist b1) m =>
m b -> m b -> m b
chooseMode (forall b. ByteString -> Handler b (Heist b) ()
cHeistServeSingle ByteString
t) (forall b. ByteString -> Handler b (Heist b) ()
heistServeSingle ByteString
t)


------------------------------------------------------------------------------
heistLocal' :: SnapletLens (Snaplet b) (Heist b)
            -> (HeistState (Handler b b) -> HeistState (Handler b b))
            -> Handler b v a
            -> Handler b v a
heistLocal' :: forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Handler b v a
-> Handler b v a
heistLocal' SnapletLens (Snaplet b) (Heist b)
heist HeistState (Handler b b) -> HeistState (Handler b b)
f Handler b v a
m = do
    Heist b
hs  <- forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall s (m :: * -> *). MonadState s m => m s
get
    forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ forall a.
(HeistState (Handler a a) -> HeistState (Handler a a))
-> Heist a -> Heist a
changeState HeistState (Handler b b) -> HeistState (Handler b b)
f
    a
res <- Handler b v a
m
    forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *). MonadState s m => s -> m ()
put Heist b
hs
    forall (m :: * -> *) a. Monad m => a -> m a
return a
res


------------------------------------------------------------------------------
heistLocal :: SnapletLens b (Heist b)
           -> (HeistState (Handler b b) -> HeistState (Handler b b))
           -> Handler b v a
           -> Handler b v a
heistLocal :: forall b v a.
SnapletLens b (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Handler b v a
-> Handler b v a
heistLocal SnapletLens b (Heist b)
heist HeistState (Handler b b) -> HeistState (Handler b b)
f Handler b v a
m = forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Handler b v a
-> Handler b v a
heistLocal' (forall a b. SnapletLens a b -> SnapletLens (Snaplet a) b
subSnaplet SnapletLens b (Heist b)
heist) HeistState (Handler b b) -> HeistState (Handler b b)
f Handler b v a
m


------------------------------------------------------------------------------
withSplices' :: SnapletLens (Snaplet b) (Heist b)
             -> Splices (SnapletISplice b)
             -> Handler b v a
             -> Handler b v a
withSplices' :: forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
withSplices' SnapletLens (Snaplet b) (Heist b)
heist Splices (SnapletISplice b)
splices Handler b v a
m = do
    forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> (HeistState (Handler b b) -> HeistState (Handler b b))
-> Handler b v a
-> Handler b v a
heistLocal' SnapletLens (Snaplet b) (Heist b)
heist (forall (n :: * -> *).
Splices (Splice n) -> HeistState n -> HeistState n
I.bindSplices Splices (SnapletISplice b)
splices) Handler b v a
m


------------------------------------------------------------------------------
withSplices :: SnapletLens b (Heist b)
            -> Splices (SnapletISplice b)
            -> Handler b v a
            -> Handler b v a
withSplices :: forall b v a.
SnapletLens b (Heist b)
-> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
withSplices SnapletLens b (Heist b)
heist Splices (SnapletISplice b)
splices Handler b v a
m = forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
withSplices' (forall a b. SnapletLens a b -> SnapletLens (Snaplet a) b
subSnaplet SnapletLens b (Heist b)
heist) Splices (SnapletISplice b)
splices Handler b v a
m


------------------------------------------------------------------------------
renderWithSplices' :: SnapletLens (Snaplet b) (Heist b)
                   -> ByteString
                   -> Splices (SnapletISplice b)
                   -> Handler b v ()
renderWithSplices' :: forall b v.
SnapletLens (Snaplet b) (Heist b)
-> ByteString -> Splices (SnapletISplice b) -> Handler b v ()
renderWithSplices' SnapletLens (Snaplet b) (Heist b)
heist ByteString
t Splices (SnapletISplice b)
splices =
    forall b v a.
SnapletLens (Snaplet b) (Heist b)
-> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
withSplices' SnapletLens (Snaplet b) (Heist b)
heist Splices (SnapletISplice b)
splices forall a b. (a -> b) -> a -> b
$ forall (m :: * -> * -> * -> *) b v' a v.
MonadSnaplet m =>
SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
withTop' SnapletLens (Snaplet b) (Heist b)
heist forall a b. (a -> b) -> a -> b
$ forall b. ByteString -> Handler b (Heist b) ()
render ByteString
t


------------------------------------------------------------------------------
renderWithSplices :: SnapletLens b (Heist b)
                  -> ByteString
                  -> Splices (SnapletISplice b)
                  -> Handler b v ()
renderWithSplices :: forall b v.
SnapletLens b (Heist b)
-> ByteString -> Splices (SnapletISplice b) -> Handler b v ()
renderWithSplices SnapletLens b (Heist b)
heist ByteString
t Splices (SnapletISplice b)
splices =
    forall b v.
SnapletLens (Snaplet b) (Heist b)
-> ByteString -> Splices (SnapletISplice b) -> Handler b v ()
renderWithSplices' (forall a b. SnapletLens a b -> SnapletLens (Snaplet a) b
subSnaplet SnapletLens b (Heist b)
heist) ByteString
t Splices (SnapletISplice b)
splices