{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module Heist
(
loadTemplates
, reloadTemplates
, addTemplatePathPrefix
, initHeist
, initHeistWithCacheTag
, defaultInterpretedSplices
, defaultLoadTimeSplices
, emptyHeistConfig
, SpliceConfig
, HeistConfig
, TemplateRepo
, TemplateLocation
, Template
, TPath
, MIMEType
, DocumentFile(..)
, AttrSplice
, RuntimeSplice
, Chunk
, HeistState
, SpliceError(..)
, CompileException(..)
, HeistT
, scInterpretedSplices
, scLoadTimeSplices
, scCompiledSplices
, scAttributeSplices
, scTemplateLocations
, scCompiledTemplateFilter
, hcSpliceConfig
, hcNamespace
, hcErrorNotBound
, hcInterpretedSplices
, hcLoadTimeSplices
, hcCompiledSplices
, hcAttributeSplices
, hcTemplateLocations
, hcCompiledTemplateFilter
, templateNames
, compiledTemplateNames
, hasTemplate
, spliceNames
, compiledSpliceNames
, evalHeistT
, getParamNode
, getContext
, getTemplateFilePath
, localParamNode
, getsHS
, getHS
, putHS
, modifyHS
, restoreHS
, localHS
, getDoc
, getXMLDoc
, tellSpliceError
, spliceErrorText
, orError
, Splices
) where
import Control.Exception.Lifted
import Control.Monad.State
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString as B
import Data.Either
import qualified Data.Foldable as F
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as Map
import qualified Data.HeterogeneousEnvironment as HE
import Data.Map.Syntax
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid
#endif
import Data.Text (Text)
import qualified Data.Text as T
import System.Directory.Tree
import qualified Text.XmlHtml as X
import Heist.Common
import qualified Heist.Compiled.Internal as C
import qualified Heist.Interpreted.Internal as I
import Heist.Splices
import Heist.Internal.Types
defaultLoadTimeSplices :: MonadIO m => Splices (I.Splice m)
defaultLoadTimeSplices :: Splices (Splice m)
defaultLoadTimeSplices = do
Splices (Splice m)
forall (m :: * -> *). MonadIO m => Splices (Splice m)
defaultInterpretedSplices
Text
"content" Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
#! Splice m
forall (m :: * -> *). Monad m => Splice m
deprecatedContentCheck
defaultInterpretedSplices :: MonadIO m => Splices (I.Splice m)
defaultInterpretedSplices :: Splices (Splice m)
defaultInterpretedSplices = do
Text
applyTag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
## Splice m
forall (m :: * -> *). Monad m => Splice m
applyImpl
Text
bindTag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
## Splice m
forall (m :: * -> *). Monad m => Splice m
bindImpl
Text
ignoreTag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
## Splice m
forall (m :: * -> *). Monad m => Splice m
ignoreImpl
Text
markdownTag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
## Splice m
forall (m :: * -> *). MonadIO m => Splice m
markdownSplice
emptyHeistConfig :: HeistConfig m
emptyHeistConfig :: HeistConfig m
emptyHeistConfig = SpliceConfig m -> Text -> Bool -> HeistConfig m
forall (m :: * -> *).
SpliceConfig m -> Text -> Bool -> HeistConfig m
HeistConfig SpliceConfig m
forall a. Monoid a => a
mempty Text
"h" Bool
True
allErrors :: [Either String (TPath, v)]
-> Either [String] (HashMap TPath v)
allErrors :: [Either String (TPath, v)] -> Either [String] (HashMap TPath v)
allErrors [Either String (TPath, v)]
tlist =
case [String]
errs of
[] -> HashMap TPath v -> Either [String] (HashMap TPath v)
forall a b. b -> Either a b
Right (HashMap TPath v -> Either [String] (HashMap TPath v))
-> HashMap TPath v -> Either [String] (HashMap TPath v)
forall a b. (a -> b) -> a -> b
$ [(TPath, v)] -> HashMap TPath v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList ([(TPath, v)] -> HashMap TPath v)
-> [(TPath, v)] -> HashMap TPath v
forall a b. (a -> b) -> a -> b
$ [Either String (TPath, v)] -> [(TPath, v)]
forall a b. [Either a b] -> [b]
rights [Either String (TPath, v)]
tlist
[String]
_ -> [String] -> Either [String] (HashMap TPath v)
forall a b. a -> Either a b
Left [String]
errs
where
errs :: [String]
errs = [Either String (TPath, v)] -> [String]
forall a b. [Either a b] -> [a]
lefts [Either String (TPath, v)]
tlist
loadTemplates :: FilePath -> IO (Either [String] TemplateRepo)
loadTemplates :: String -> IO (Either [String] TemplateRepo)
loadTemplates String
dir = do
AnchoredDirTree [Either String (TPath, DocumentFile)]
d <- (String -> IO [Either String (TPath, DocumentFile)])
-> String
-> IO (AnchoredDirTree [Either String (TPath, DocumentFile)])
forall a. (String -> IO a) -> String -> IO (AnchoredDirTree a)
readDirectoryWith (String -> String -> IO [Either String (TPath, DocumentFile)]
loadTemplate String
dir) String
dir
#if MIN_VERSION_directory_tree(0,11,0)
Either [String] TemplateRepo -> IO (Either [String] TemplateRepo)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] TemplateRepo -> IO (Either [String] TemplateRepo))
-> Either [String] TemplateRepo
-> IO (Either [String] TemplateRepo)
forall a b. (a -> b) -> a -> b
$ [Either String (TPath, DocumentFile)]
-> Either [String] TemplateRepo
forall v.
[Either String (TPath, v)] -> Either [String] (HashMap TPath v)
allErrors ([Either String (TPath, DocumentFile)]
-> Either [String] TemplateRepo)
-> [Either String (TPath, DocumentFile)]
-> Either [String] TemplateRepo
forall a b. (a -> b) -> a -> b
$ DirTree [Either String (TPath, DocumentFile)]
-> [Either String (TPath, DocumentFile)]
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold (AnchoredDirTree [Either String (TPath, DocumentFile)]
-> DirTree [Either String (TPath, DocumentFile)]
forall a. AnchoredDirTree a -> DirTree a
dirTree AnchoredDirTree [Either String (TPath, DocumentFile)]
d)
#else
return $ allErrors $ F.fold (free d)
#endif
reloadTemplates :: TemplateRepo -> IO (Either [String] TemplateRepo)
reloadTemplates :: TemplateRepo -> IO (Either [String] TemplateRepo)
reloadTemplates TemplateRepo
repo = do
[Either String (TPath, DocumentFile)]
tlist <- ((TPath, DocumentFile) -> IO (Either String (TPath, DocumentFile)))
-> [(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (TPath, DocumentFile) -> IO (Either String (TPath, DocumentFile))
forall t. (t, DocumentFile) -> IO (Either String (t, DocumentFile))
loadOrKeep ([(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)])
-> [(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)]
forall a b. (a -> b) -> a -> b
$ TemplateRepo -> [(TPath, DocumentFile)]
forall k v. HashMap k v -> [(k, v)]
Map.toList TemplateRepo
repo
Either [String] TemplateRepo -> IO (Either [String] TemplateRepo)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] TemplateRepo -> IO (Either [String] TemplateRepo))
-> Either [String] TemplateRepo
-> IO (Either [String] TemplateRepo)
forall a b. (a -> b) -> a -> b
$ [Either String (TPath, DocumentFile)]
-> Either [String] TemplateRepo
forall v.
[Either String (TPath, v)] -> Either [String] (HashMap TPath v)
allErrors [Either String (TPath, DocumentFile)]
tlist
where
loadOrKeep :: (t, DocumentFile) -> IO (Either String (t, DocumentFile))
loadOrKeep (t
p,DocumentFile
df) =
case DocumentFile -> Maybe String
dfFile DocumentFile
df of
Maybe String
Nothing -> Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile)))
-> Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile))
forall a b. (a -> b) -> a -> b
$ (t, DocumentFile) -> Either String (t, DocumentFile)
forall a b. b -> Either a b
Right (t
p, DocumentFile
df)
Just String
fp -> do
[Either String DocumentFile]
df' <- String -> IO [Either String DocumentFile]
loadTemplate' String
fp
Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile)))
-> Either String (t, DocumentFile)
-> IO (Either String (t, DocumentFile))
forall a b. (a -> b) -> a -> b
$ (DocumentFile -> (t, DocumentFile))
-> Either String DocumentFile -> Either String (t, DocumentFile)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t
p,) (Either String DocumentFile -> Either String (t, DocumentFile))
-> Either String DocumentFile -> Either String (t, DocumentFile)
forall a b. (a -> b) -> a -> b
$ case [Either String DocumentFile]
df' of
[Either String DocumentFile
t] -> Either String DocumentFile
t
[Either String DocumentFile]
_ -> String -> Either String DocumentFile
forall a b. a -> Either a b
Left String
"Template repo has non-templates"
addTemplatePathPrefix :: ByteString -> TemplateRepo -> TemplateRepo
addTemplatePathPrefix :: ByteString -> TemplateRepo -> TemplateRepo
addTemplatePathPrefix ByteString
dir TemplateRepo
ts
| ByteString -> Bool
B.null ByteString
dir = TemplateRepo
ts
| Bool
otherwise = [(TPath, DocumentFile)] -> TemplateRepo
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList ([(TPath, DocumentFile)] -> TemplateRepo)
-> [(TPath, DocumentFile)] -> TemplateRepo
forall a b. (a -> b) -> a -> b
$
((TPath, DocumentFile) -> (TPath, DocumentFile))
-> [(TPath, DocumentFile)] -> [(TPath, DocumentFile)]
forall a b. (a -> b) -> [a] -> [b]
map (\(TPath
x,DocumentFile
y) -> (TPath -> TPath
f TPath
x, DocumentFile
y)) ([(TPath, DocumentFile)] -> [(TPath, DocumentFile)])
-> [(TPath, DocumentFile)] -> [(TPath, DocumentFile)]
forall a b. (a -> b) -> a -> b
$
TemplateRepo -> [(TPath, DocumentFile)]
forall k v. HashMap k v -> [(k, v)]
Map.toList TemplateRepo
ts
where
f :: TPath -> TPath
f TPath
ps = TPath
psTPath -> TPath -> TPath
forall a. [a] -> [a] -> [a]
++ByteString -> TPath
splitTemplatePath ByteString
dir
emptyHS :: HE.KeyGen -> HeistState m
emptyHS :: KeyGen -> HeistState m
emptyHS KeyGen
kg = HashMap Text (HeistT m m Template)
-> TemplateRepo
-> HashMap Text (HeistT m IO (DList (Chunk m)))
-> HashMap TPath ([Chunk m], ByteString)
-> HashMap Text (AttrSplice m)
-> Bool
-> TPath
-> [(TPath, Maybe String, Text)]
-> Int
-> [DocType]
-> Maybe String
-> KeyGen
-> Bool
-> Markup
-> Text
-> [SpliceError]
-> Bool
-> Int
-> HeistState m
forall (m :: * -> *).
HashMap Text (HeistT m m Template)
-> TemplateRepo
-> HashMap Text (HeistT m IO (DList (Chunk m)))
-> HashMap TPath ([Chunk m], ByteString)
-> HashMap Text (AttrSplice m)
-> Bool
-> TPath
-> [(TPath, Maybe String, Text)]
-> Int
-> [DocType]
-> Maybe String
-> KeyGen
-> Bool
-> Markup
-> Text
-> [SpliceError]
-> Bool
-> Int
-> HeistState m
HeistState HashMap Text (HeistT m m Template)
forall k v. HashMap k v
Map.empty TemplateRepo
forall k v. HashMap k v
Map.empty HashMap Text (HeistT m IO (DList (Chunk m)))
forall k v. HashMap k v
Map.empty HashMap TPath ([Chunk m], ByteString)
forall k v. HashMap k v
Map.empty HashMap Text (AttrSplice m)
forall k v. HashMap k v
Map.empty
Bool
True [] [] Int
0 [] Maybe String
forall a. Maybe a
Nothing KeyGen
kg Bool
False Markup
Html Text
"" [] Bool
False Int
0
initHeist :: Monad n
=> HeistConfig n
-> IO (Either [String] (HeistState n))
initHeist :: HeistConfig n -> IO (Either [String] (HeistState n))
initHeist HeistConfig n
hc = do
KeyGen
keyGen <- IO KeyGen
HE.newKeyGen
[Either [String] TemplateRepo]
repos <- [IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo])
-> [IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo]
forall a b. (a -> b) -> a -> b
$ SpliceConfig n -> [IO (Either [String] TemplateRepo)]
forall (m :: * -> *).
SpliceConfig m -> [IO (Either [String] TemplateRepo)]
_scTemplateLocations (SpliceConfig n -> [IO (Either [String] TemplateRepo)])
-> SpliceConfig n -> [IO (Either [String] TemplateRepo)]
forall a b. (a -> b) -> a -> b
$ HeistConfig n -> SpliceConfig n
forall (m :: * -> *). HeistConfig m -> SpliceConfig m
_hcSpliceConfig HeistConfig n
hc
case [Either [String] TemplateRepo] -> Either [String] [TemplateRepo]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Either [String] TemplateRepo]
repos of
Left [String]
es -> Either [String] (HeistState n)
-> IO (Either [String] (HeistState n))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] (HeistState n)
-> IO (Either [String] (HeistState n)))
-> Either [String] (HeistState n)
-> IO (Either [String] (HeistState n))
forall a b. (a -> b) -> a -> b
$ [String] -> Either [String] (HeistState n)
forall a b. a -> Either a b
Left [String]
es
Right [TemplateRepo]
rs -> KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
forall (n :: * -> *).
Monad n =>
KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
initHeist' KeyGen
keyGen HeistConfig n
hc ([TemplateRepo] -> TemplateRepo
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
Map.unions [TemplateRepo]
rs)
mkSplicePrefix :: Text -> Text
mkSplicePrefix :: Text -> Text
mkSplicePrefix Text
ns
| Text -> Bool
T.null Text
ns = Text
""
| Bool
otherwise = Text
ns Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` Text
":"
initHeist' :: Monad n
=> HE.KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
initHeist' :: KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
initHeist' KeyGen
keyGen (HeistConfig SpliceConfig n
sc Text
ns Bool
enn) TemplateRepo
repo = do
let empty :: HeistState m
empty = KeyGen -> HeistState m
forall (m :: * -> *). KeyGen -> HeistState m
emptyHS KeyGen
keyGen
let (SpliceConfig Splices (Splice n)
i Splices (Splice IO)
lt Splices (Splice n)
c Splices (AttrSplice n)
a [IO (Either [String] TemplateRepo)]
_ TPath -> Bool
f) = SpliceConfig n
sc
Either [String] TemplateRepo
etmap <- KeyGen
-> Splices (Splice IO)
-> TemplateRepo
-> Text
-> IO (Either [String] TemplateRepo)
preproc KeyGen
keyGen Splices (Splice IO)
lt TemplateRepo
repo Text
ns
let prefix :: Text
prefix = Text -> Text
mkSplicePrefix Text
ns
let eis :: Either [String] (HashMap Text (Splice n))
eis = Splices (Splice n) -> Either [String] (HashMap Text (Splice n))
forall s. Splices s -> Either [String] (HashMap Text s)
runHashMap (Splices (Splice n) -> Either [String] (HashMap Text (Splice n)))
-> Splices (Splice n) -> Either [String] (HashMap Text (Splice n))
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> Splices (Splice n) -> Splices (Splice n)
forall k1 k2 v a. (k1 -> k2) -> MapSyntaxM k1 v a -> MapSyntax k2 v
mapK (Text
prefixText -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) Splices (Splice n)
i
ecs :: Either [String] (HashMap Text (Splice n))
ecs = Splices (Splice n) -> Either [String] (HashMap Text (Splice n))
forall s. Splices s -> Either [String] (HashMap Text s)
runHashMap (Splices (Splice n) -> Either [String] (HashMap Text (Splice n)))
-> Splices (Splice n) -> Either [String] (HashMap Text (Splice n))
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> Splices (Splice n) -> Splices (Splice n)
forall k1 k2 v a. (k1 -> k2) -> MapSyntaxM k1 v a -> MapSyntax k2 v
mapK (Text
prefixText -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) Splices (Splice n)
c
eas :: Either [String] (HashMap Text (AttrSplice n))
eas = Splices (AttrSplice n)
-> Either [String] (HashMap Text (AttrSplice n))
forall s. Splices s -> Either [String] (HashMap Text s)
runHashMap (Splices (AttrSplice n)
-> Either [String] (HashMap Text (AttrSplice n)))
-> Splices (AttrSplice n)
-> Either [String] (HashMap Text (AttrSplice n))
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> Splices (AttrSplice n) -> Splices (AttrSplice n)
forall k1 k2 v a. (k1 -> k2) -> MapSyntaxM k1 v a -> MapSyntax k2 v
mapK (Text
prefixText -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) Splices (AttrSplice n)
a
let hs1 :: Either [String] (HeistState n)
hs1 = do
TemplateRepo
tmap <- Either [String] TemplateRepo
etmap
HashMap Text (Splice n)
is <- Either [String] (HashMap Text (Splice n))
eis
HashMap Text (Splice n)
cs <- Either [String] (HashMap Text (Splice n))
ecs
HashMap Text (AttrSplice n)
as <- Either [String] (HashMap Text (AttrSplice n))
eas
HeistState n -> Either [String] (HeistState n)
forall (m :: * -> *) a. Monad m => a -> m a
return (HeistState n -> Either [String] (HeistState n))
-> HeistState n -> Either [String] (HeistState n)
forall a b. (a -> b) -> a -> b
$ HeistState n
forall (m :: * -> *). HeistState m
empty { _spliceMap :: HashMap Text (Splice n)
_spliceMap = HashMap Text (Splice n)
is
, _templateMap :: TemplateRepo
_templateMap = TemplateRepo
tmap
, _compiledSpliceMap :: HashMap Text (Splice n)
_compiledSpliceMap = HashMap Text (Splice n)
cs
, _attrSpliceMap :: HashMap Text (AttrSplice n)
_attrSpliceMap = HashMap Text (AttrSplice n)
as
, _splicePrefix :: Text
_splicePrefix = Text
prefix
, _errorNotBound :: Bool
_errorNotBound = Bool
enn
}
([String] -> IO (Either [String] (HeistState n)))
-> (HeistState n -> IO (Either [String] (HeistState n)))
-> Either [String] (HeistState n)
-> IO (Either [String] (HeistState n))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Either [String] (HeistState n)
-> IO (Either [String] (HeistState n))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] (HeistState n)
-> IO (Either [String] (HeistState n)))
-> ([String] -> Either [String] (HeistState n))
-> [String]
-> IO (Either [String] (HeistState n))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Either [String] (HeistState n)
forall a b. a -> Either a b
Left) ((TPath -> Bool)
-> HeistState n -> IO (Either [String] (HeistState n))
forall (n :: * -> *).
Monad n =>
(TPath -> Bool)
-> HeistState n -> IO (Either [String] (HeistState n))
C.compileTemplates TPath -> Bool
f) Either [String] (HeistState n)
hs1
preproc :: HE.KeyGen
-> Splices (I.Splice IO)
-> TemplateRepo
-> Text
-> IO (Either [String] TemplateRepo)
preproc :: KeyGen
-> Splices (Splice IO)
-> TemplateRepo
-> Text
-> IO (Either [String] TemplateRepo)
preproc KeyGen
keyGen Splices (Splice IO)
splices TemplateRepo
templates Text
ns = do
let esm :: Either [String] (HashMap Text (Splice IO))
esm = Splices (Splice IO) -> Either [String] (HashMap Text (Splice IO))
forall s. Splices s -> Either [String] (HashMap Text s)
runHashMap Splices (Splice IO)
splices
case Either [String] (HashMap Text (Splice IO))
esm of
Left [String]
errs -> Either [String] TemplateRepo -> IO (Either [String] TemplateRepo)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] TemplateRepo -> IO (Either [String] TemplateRepo))
-> Either [String] TemplateRepo
-> IO (Either [String] TemplateRepo)
forall a b. (a -> b) -> a -> b
$ [String] -> Either [String] TemplateRepo
forall a b. a -> Either a b
Left [String]
errs
Right HashMap Text (Splice IO)
sm -> do
let hs :: HeistState IO
hs = (KeyGen -> HeistState IO
forall (m :: * -> *). KeyGen -> HeistState m
emptyHS KeyGen
keyGen) { _spliceMap :: HashMap Text (Splice IO)
_spliceMap = HashMap Text (Splice IO)
sm
, _templateMap :: TemplateRepo
_templateMap = TemplateRepo
templates
, _preprocessingMode :: Bool
_preprocessingMode = Bool
True
, _splicePrefix :: Text
_splicePrefix = Text -> Text
mkSplicePrefix Text
ns }
let eval :: HeistT IO m a -> m a
eval HeistT IO m a
a = HeistT IO m a -> Node -> HeistState IO -> m a
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
HeistT n m a -> Node -> HeistState n -> m a
evalHeistT HeistT IO m a
a (Text -> Node
X.TextNode Text
"") HeistState IO
hs
[Either String (TPath, DocumentFile)]
tPairs <- ((TPath, DocumentFile) -> IO (Either String (TPath, DocumentFile)))
-> [(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (HeistT IO IO (Either String (TPath, DocumentFile))
-> IO (Either String (TPath, DocumentFile))
forall (m :: * -> *) a. Monad m => HeistT IO m a -> m a
eval (HeistT IO IO (Either String (TPath, DocumentFile))
-> IO (Either String (TPath, DocumentFile)))
-> ((TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile)))
-> (TPath, DocumentFile)
-> IO (Either String (TPath, DocumentFile))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile))
preprocess) ([(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)])
-> [(TPath, DocumentFile)]
-> IO [Either String (TPath, DocumentFile)]
forall a b. (a -> b) -> a -> b
$ TemplateRepo -> [(TPath, DocumentFile)]
forall k v. HashMap k v -> [(k, v)]
Map.toList TemplateRepo
templates
let bad :: [String]
bad = [Either String (TPath, DocumentFile)] -> [String]
forall a b. [Either a b] -> [a]
lefts [Either String (TPath, DocumentFile)]
tPairs
Either [String] TemplateRepo -> IO (Either [String] TemplateRepo)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] TemplateRepo -> IO (Either [String] TemplateRepo))
-> Either [String] TemplateRepo
-> IO (Either [String] TemplateRepo)
forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not ([String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
bad)
then [String] -> Either [String] TemplateRepo
forall a b. a -> Either a b
Left [String]
bad
else TemplateRepo -> Either [String] TemplateRepo
forall a b. b -> Either a b
Right (TemplateRepo -> Either [String] TemplateRepo)
-> TemplateRepo -> Either [String] TemplateRepo
forall a b. (a -> b) -> a -> b
$ [(TPath, DocumentFile)] -> TemplateRepo
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList ([(TPath, DocumentFile)] -> TemplateRepo)
-> [(TPath, DocumentFile)] -> TemplateRepo
forall a b. (a -> b) -> a -> b
$ [Either String (TPath, DocumentFile)] -> [(TPath, DocumentFile)]
forall a b. [Either a b] -> [b]
rights [Either String (TPath, DocumentFile)]
tPairs
preprocess :: (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile))
preprocess :: (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile))
preprocess (TPath
tpath, DocumentFile
docFile) = do
let tname :: ByteString
tname = TPath -> ByteString
tpathName TPath
tpath
die :: a
die = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"Preprocess failed because the template `"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
BC.unpack ByteString
tname
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"` was not found in the template repository."
!Either SomeException (Maybe Document)
emdoc <- HeistT IO IO (Maybe Document)
-> HeistT IO IO (Either SomeException (Maybe Document))
forall (m :: * -> *) e a.
(MonadBaseControl IO m, Exception e) =>
m a -> m (Either e a)
try (HeistT IO IO (Maybe Document)
-> HeistT IO IO (Either SomeException (Maybe Document)))
-> HeistT IO IO (Maybe Document)
-> HeistT IO IO (Either SomeException (Maybe Document))
forall a b. (a -> b) -> a -> b
$ ByteString -> HeistT IO IO (Maybe Document)
forall (n :: * -> *).
Monad n =>
ByteString -> HeistT n n (Maybe Document)
I.evalWithDoctypes ByteString
tname
:: HeistT IO IO (Either SomeException (Maybe X.Document))
let f :: Document -> (TPath, DocumentFile)
f !Document
doc = (TPath
tpath, DocumentFile
docFile { dfDoc :: Document
dfDoc = Document
doc })
Either String (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile)))
-> Either String (TPath, DocumentFile)
-> HeistT IO IO (Either String (TPath, DocumentFile))
forall a b. (a -> b) -> a -> b
$! (SomeException -> Either String (TPath, DocumentFile))
-> (Maybe Document -> Either String (TPath, DocumentFile))
-> Either SomeException (Maybe Document)
-> Either String (TPath, DocumentFile)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Either String (TPath, DocumentFile)
forall a b. a -> Either a b
Left (String -> Either String (TPath, DocumentFile))
-> (SomeException -> String)
-> SomeException
-> Either String (TPath, DocumentFile)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall a. Show a => a -> String
show) ((TPath, DocumentFile) -> Either String (TPath, DocumentFile)
forall a b. b -> Either a b
Right ((TPath, DocumentFile) -> Either String (TPath, DocumentFile))
-> (Maybe Document -> (TPath, DocumentFile))
-> Maybe Document
-> Either String (TPath, DocumentFile)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TPath, DocumentFile)
-> (Document -> (TPath, DocumentFile))
-> Maybe Document
-> (TPath, DocumentFile)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (TPath, DocumentFile)
forall a. a
die Document -> (TPath, DocumentFile)
f) Either SomeException (Maybe Document)
emdoc
initHeistWithCacheTag :: MonadIO n
=> HeistConfig n
-> IO (Either [String] (HeistState n, CacheTagState))
initHeistWithCacheTag :: HeistConfig n -> IO (Either [String] (HeistState n, CacheTagState))
initHeistWithCacheTag (HeistConfig SpliceConfig n
sc Text
ns Bool
enn) = do
(Splice IO
ss, CacheTagState
cts) <- IO (Splice IO, CacheTagState) -> IO (Splice IO, CacheTagState)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (Splice IO, CacheTagState)
mkCacheTag
let tag :: p
tag = p
"cache"
KeyGen
keyGen <- IO KeyGen
HE.newKeyGen
[Either [String] TemplateRepo]
erepos <- [IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo])
-> [IO (Either [String] TemplateRepo)]
-> IO [Either [String] TemplateRepo]
forall a b. (a -> b) -> a -> b
$ SpliceConfig n -> [IO (Either [String] TemplateRepo)]
forall (m :: * -> *).
SpliceConfig m -> [IO (Either [String] TemplateRepo)]
_scTemplateLocations SpliceConfig n
sc
case [Either [String] TemplateRepo] -> Either [String] [TemplateRepo]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Either [String] TemplateRepo]
erepos of
Left [String]
es -> Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState)))
-> Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall a b. (a -> b) -> a -> b
$ [String] -> Either [String] (HeistState n, CacheTagState)
forall a b. a -> Either a b
Left [String]
es
Right [TemplateRepo]
repos -> do
Either [String] TemplateRepo
eRawWithCache <- KeyGen
-> Splices (Splice IO)
-> TemplateRepo
-> Text
-> IO (Either [String] TemplateRepo)
preproc KeyGen
keyGen (Text
forall p. IsString p => p
tag Text -> Splice IO -> Splices (Splice IO)
forall k v. k -> v -> MapSyntax k v
## Splice IO
ss) ([TemplateRepo] -> TemplateRepo
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
Map.unions [TemplateRepo]
repos) Text
ns
case Either [String] TemplateRepo
eRawWithCache of
Left [String]
es -> Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState)))
-> Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall a b. (a -> b) -> a -> b
$ [String] -> Either [String] (HeistState n, CacheTagState)
forall a b. a -> Either a b
Left [String]
es
Right TemplateRepo
rawWithCache -> do
let sc' :: SpliceConfig m
sc' = Splices (Splice m)
-> Splices (Splice IO)
-> Splices (Splice m)
-> Splices (AttrSplice m)
-> [IO (Either [String] TemplateRepo)]
-> (TPath -> Bool)
-> SpliceConfig m
forall (m :: * -> *).
Splices (Splice m)
-> Splices (Splice IO)
-> Splices (Splice m)
-> Splices (AttrSplice m)
-> [IO (Either [String] TemplateRepo)]
-> (TPath -> Bool)
-> SpliceConfig m
SpliceConfig (Text
forall p. IsString p => p
tag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
#! CacheTagState -> Splice m
forall (n :: * -> *). MonadIO n => CacheTagState -> Splice n
cacheImpl CacheTagState
cts) Splices (Splice IO)
forall a. Monoid a => a
mempty
(Text
forall p. IsString p => p
tag Text -> Splice m -> Splices (Splice m)
forall k v. k -> v -> MapSyntax k v
#! CacheTagState -> Splice m
forall (n :: * -> *). MonadIO n => CacheTagState -> Splice n
cacheImplCompiled CacheTagState
cts)
Splices (AttrSplice m)
forall a. Monoid a => a
mempty [IO (Either [String] TemplateRepo)]
forall a. Monoid a => a
mempty (Bool -> TPath -> Bool
forall a b. a -> b -> a
const Bool
True)
let hc :: HeistConfig n
hc = SpliceConfig n -> Text -> Bool -> HeistConfig n
forall (m :: * -> *).
SpliceConfig m -> Text -> Bool -> HeistConfig m
HeistConfig (SpliceConfig n -> SpliceConfig n -> SpliceConfig n
forall a. Monoid a => a -> a -> a
mappend SpliceConfig n
sc SpliceConfig n
forall (m :: * -> *). MonadIO m => SpliceConfig m
sc') Text
ns Bool
enn
Either [String] (HeistState n)
hs <- KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
forall (n :: * -> *).
Monad n =>
KeyGen
-> HeistConfig n
-> TemplateRepo
-> IO (Either [String] (HeistState n))
initHeist' KeyGen
keyGen HeistConfig n
hc TemplateRepo
rawWithCache
Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState)))
-> Either [String] (HeistState n, CacheTagState)
-> IO (Either [String] (HeistState n, CacheTagState))
forall a b. (a -> b) -> a -> b
$ (HeistState n -> (HeistState n, CacheTagState))
-> Either [String] (HeistState n)
-> Either [String] (HeistState n, CacheTagState)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (,CacheTagState
cts) Either [String] (HeistState n)
hs