@@ -0,0 +1,49 @@
1+module Hakyll.Web.Template
8+import Data.List (isPrefixOf)
9+import Data.Char (isAlphaNum)
10+import Data.Maybe (fromMaybe)
11+import qualified Data.Map as M
13+import Hakyll.Web.Template.Internal
14+import Hakyll.Web.Page
16+-- | Construct a @Template@ from a string.
18+readTemplate :: String -> Template
19+readTemplate = Template . readTemplate'
21+ readTemplate' [] = []
23+ | "$$" `isPrefixOf` string =
24+ EscapeCharacter : (readTemplate' $ drop 2 string)
25+ | "$" `isPrefixOf` string =
26+ let (key, rest) = span isAlphaNum $ drop 1 string
27+ in Identifier key : readTemplate' rest
29+ let (chunk, rest) = break (== '$') string
30+ in Chunk chunk : readTemplate' rest
32+-- | Substitutes @$identifiers@ in the given @Template@ by values from the given
33+-- "Page". When a key is not found, it is left as it is. You can specify
34+-- the characters used to replace escaped dollars (@$$@) here.
36+applyTemplate :: Template -> Page String -> Page String
37+applyTemplate template page =
38+ fmap (const $ substitute =<< unTemplate template) page
40+ substitute (Chunk chunk) = chunk
41+ substitute (Identifier key) =
42+ fromMaybe ('$' : key) $ M.lookup key $ toMap page
43+ substitute (EscapeCharacter) = "$"
45+-- | Apply a page as it's own template. This is often very useful to fill in
46+-- certain keys like @$root@ and @$url@.
48+applySelf :: Page String -> Page String
49+applySelf page = applyTemplate (readTemplate $ pageBody page) page