wobsurv-0.1.0: library/Wobsurv/Util/Mustache/Renderer.hs
module Wobsurv.Util.Mustache.Renderer where
import BasePrelude
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Except
import Control.Monad.Trans.State
import qualified Data.ByteString
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text
import qualified Data.Text.Lazy
import qualified Filesystem
import qualified Filesystem.Path.CurrentOS as Path
import qualified Text.Hastache
import qualified Text.Hastache.Context
type BS =
Data.ByteString.ByteString
type Text =
Data.Text.Text
type LazyText =
Data.Text.Lazy.Text
type Path =
Path.FilePath
-- |
-- A fast Hastache renderer,
-- which preloads all templates instead of reading them during each rendering.
type Renderer =
TemplatesCache
-- |
-- Mappings from template names to their contents
-- stored in RAM for faster processing.
--
-- Supposed to be loaded once during the initialization of the app.
type TemplatesCache =
HashMap.HashMap TemplateName Text
type TemplateName =
Text
type Context =
HashMap.HashMap Text Value
data Value where
Variable :: Text.Hastache.MuVar a => a -> Value
Contexts :: [Context] -> Value
-- |
-- Initialize a renderer by loading all templates from the specified folder.
new :: Path -> IO Renderer
new path =
initTemplatesCache
where
initTemplatesCache =
flip execStateT mempty $ do
subpaths <- lift $ Filesystem.listDirectory path
forM_ subpaths $ \subpath -> do
contents <- lift $ Filesystem.readTextFile subpath
modify $ HashMap.insert (fromString $ Path.encodeString $ Path.basename subpath) contents
-- |
-- Workarounds over Hastache API to enable it with caching.
render :: (Data model) => model -> TemplateName -> Renderer -> Maybe LazyText
render model name cache =
do
template <- HashMap.lookup name cache
return $ unsafePerformIO $
Text.Hastache.hastacheStr config template context
where
config =
Text.Hastache.MuConfig Text.Hastache.htmlEscape Nothing Nothing getTemplate
where
getTemplate s =
return $ HashMap.lookup (fromString s) cache
context =
Text.Hastache.Context.mkGenericContext model