module Text.Hakyll.Internal.Template
( Template (..)
, fromString
, readTemplate
, substitute
, regularSubstitute
, finalSubstitute
) where
import Control.Arrow ((>>>))
import Control.Applicative ((<$>))
import Data.List (isPrefixOf)
import Data.Char (isAlphaNum)
import Data.Maybe (fromMaybe)
import System.FilePath ((</>))
import qualified Data.Map as M
import Text.Hakyll.Context (Context (..))
import Text.Hakyll.HakyllMonad (Hakyll)
import Text.Hakyll.HakyllAction
import Text.Hakyll.Pandoc
import Text.Hakyll.Internal.Cache
import Text.Hakyll.Page
import Text.Hakyll.ContextManipulations
import Text.Hakyll.Internal.Template.Template
import Text.Hakyll.Internal.Template.Hamlet
fromString :: String -> Template
fromString = Template . fromString'
where
fromString' [] = []
fromString' string
| "$$" `isPrefixOf` string =
EscapeCharacter : (fromString' $ drop 2 string)
| "$" `isPrefixOf` string =
let (key, rest) = span isAlphaNum $ drop 1 string
in Identifier key : fromString' rest
| otherwise =
let (chunk, rest) = break (== '$') string
in Chunk chunk : fromString' rest
readTemplate :: FilePath -> Hakyll Template
readTemplate path = do
isCacheMoreRecent' <- isCacheMoreRecent fileName [path]
if isCacheMoreRecent'
then getFromCache fileName
else do
template <- if isHamletRTFile path
then readHamletTemplate
else readDefaultTemplate
storeInCache template fileName
return template
where
fileName = "templates" </> path
readDefaultTemplate = do
body <- runHakyllAction $ readPageAction path
>>> renderAction
>>> takeBody
return $ fromString body
readHamletTemplate = fromHamletRT <$> readHamletRT path
substitute :: String -> Template -> Context -> String
substitute escaper template context = substitute' =<< unTemplate template
where
substitute' (Chunk chunk) = chunk
substitute' (Identifier key) =
fromMaybe ('$' : key) $ M.lookup key $ unContext context
substitute' (EscapeCharacter) = escaper
regularSubstitute :: Template -> Context -> String
regularSubstitute = substitute "$$"
finalSubstitute :: Template -> Context -> String
finalSubstitute = substitute "$"