press-0.1.0: Text/Press/Run.hs
module Text.Press.Run where
import Control.Monad.State
import Control.Monad.Error (runErrorT, ErrorT)
import Control.Monad.Error.Class (throwError)
import Control.Monad.Writer.Lazy
import Prelude hiding (lookup)
import Data.Map (insert, lookup)
import Text.JSON (JSValue, decodeStrict, JSValue(..))
import Text.Press.Types
import Text.Press.Parser
import Text.Press.Render
import Text.Press.Tags
type Result = Either PressError [String]
runJSValuesWithPath datas templateName = runErrorT $ evalStateT (runJSValuesWithPathStTErrT datas templateName) defaultParser
runJSValuesWithPathStTErrT :: [JSValue] -> String -> StateT Parser (ErrorT PressError IO) [String]
runJSValuesWithPathStTErrT datas templateName = do
addToTemplateCache templateName
parser <- get
template <- fmap head $ lookupTemplates templateName
let st = RenderState {
renderStateParser = parser,
renderStateTemplate = template,
renderStateValues = datas
}
lift $ evalStateT (execWriterT doRender) st
runJSValuesWithBody :: [JSValue] -> String -> IO Result
runJSValuesWithBody jsvalues body = do
case parseString defaultParser body of
Left parsecError -> return $ Left $ ParseError parsecError
Right template -> runErrorT $ evalStateT (runJSValuesWithTemplateStTErrT jsvalues template) defaultParser
runJSValuesWithTemplate :: [JSValue] -> Template -> Parser -> IO Result
runJSValuesWithTemplate jsvalues template parser = runErrorT $ evalStateT (runJSValuesWithTemplateStTErrT jsvalues template) parser
runJSValuesWithTemplateStTErrT :: [JSValue] -> Template -> StateT Parser (ErrorT PressError IO) [String]
runJSValuesWithTemplateStTErrT jsvalues template = do
case tmplExtends template of
Just s -> addToTemplateCache s
Nothing -> return ()
parser <- get
lift $ evalStateT (execWriterT doRender) RenderState {
renderStateParser = parser,
renderStateTemplate = template,
renderStateValues = jsvalues
}
lookupTemplates templateName = do
parser <- get
case lookup templateName (parserTemplateCache parser) of
Just template -> case tmplExtends template of
Nothing -> return [template]
Just s -> do
xs <- lookupTemplates s
return $ template : xs
Nothing -> throwError $ PressError $ "unexpected uncached template: " ++ (show templateName)
addToTemplateCache template = do
parser <- get
let mapping = parserTemplateCache parser
case lookup template mapping of
Just tmpl -> return ()
Nothing -> do
eitherTemplateError <- liftIO $ parseFile parser template
case eitherTemplateError of
Left err -> liftIO $ error . show $ err
Right tmpl -> do
let mapping' = insert template tmpl mapping
put $ parser {parserTemplateCache = mapping'}
case tmplExtends tmpl of
Nothing -> return ()
Just s -> addToTemplateCache s
defaultParser = newParser { parserTagTypes = defaultTagTypes }