@@ -58,66 +58,78 @@
58-- > <a href="/about.html"> About
58-- > <a href="/about.html"> About
59-- > <a href="/code.html"> Code
59-- > <a href="/code.html"> Code
60-- > #{body}
60-- > #{body}
61−--
61+{-# LANGUAGE Arrows #-}
62+{-# LANGUAGE ScopedTypeVariables #-}
62module Hakyll.Web.Template
63module Hakyll.Web.Template
63 ( Template
64 ( Template
64 , applyTemplate
65 , applyTemplate
65− , applyTemplateWith
66+ , applyTemplateToPage
66 , applySelf
67 , applySelf
67 , templateCompiler
68 , templateCompiler
68 , templateCompilerWith
69 , templateCompilerWith
69 , applyTemplateCompiler
70 , applyTemplateCompiler
70− , applyTemplateCompilerWith
74−import Data.Maybe (fromMaybe)
75−import System.FilePath (takeExtension)
76−import qualified Data.Map as M
74+--------------------------------------------------------------------------------
76+import Control.Category (id)
77+import qualified Data.Map as M
78+import Data.Maybe (fromMaybe)
79+import Prelude hiding (id)
80+import System.FilePath (takeExtension)
78−import Text.Hamlet (HamletSettings, defaultHamletSettings)
81+import Text.Hamlet (HamletSettings,
82+ defaultHamletSettings)
84+--------------------------------------------------------------------------------
80−import Hakyll.Core.Compiler
85+import Hakyll.Core.Compiler
81−import Hakyll.Core.Identifier
86+import Hakyll.Core.Identifier
82−import Hakyll.Web.Template.Internal
87+import Hakyll.Core.Util.Arrow
83−import Hakyll.Web.Template.Read
84−import Hakyll.Web.Page.Internal
88+import Hakyll.Web.Page.Internal
89+import Hakyll.Web.Template.Internal
90+import Hakyll.Web.Template.Read
86−-- | Substitutes @$identifiers@ in the given @Template@ by values from the given
87−-- "Page". When a key is not found, it is left as it is.
89−applyTemplate :: Template -> Page String -> Page String
90−applyTemplate = applyTemplateWith defaultMissingHandler
92−-- | Default solution if a key is missing: render it again
93+--------------------------------------------------------------------------------
93−defaultMissingHandler :: String -> String
94+applyTemplate :: forall a b. (ArrowChoice a, ArrowMap a)
94−defaultMissingHandler k = "$" ++ k ++ "$"
95+ => a (String, b) String
96+ -> a (Template, b) String
98+ arr (\(tpl, x) -> [(e, x) | e <- unTemplate tpl]) >>>
99+ mapA applyElement >>^ concat
101+ applyElement :: a (TemplateElement, b) String
102+ applyElement = unElement >>> (id ||| field)
96−-- | A version of 'applyTemplate' which allows you to give a fallback option,
104+ unElement :: a (TemplateElement, b) (Either String (String, b))
97−-- which can produce the value for a key if it is missing.
105+ unElement = arr $ \(e, x) -> case e of
98−--
106+ Chunk c -> Left c
99−applyTemplateWith :: (String -> String) -- ^ Fallback if key missing
107+ Escaped -> Left "$"
100− -> Template -- ^ Template to apply
108+ Key k -> Right (k, x)
101− -> Page String -- ^ Input page
109+
102− -> Page String -- ^ Resulting page
110+
103−applyTemplateWith missing template page =
111+--------------------------------------------------------------------------------
104− fmap (const $ substitute =<< unTemplate template) page
112+-- | TODO: Remove
113+applyTemplateToPage :: Template -> Page String -> Page String
114+applyTemplateToPage tpl page =
115+ fmap (const $ applyTemplate pageField (tpl, page)) page
106− map' = toMap page
117+ pageField (k, p) = fromMaybe ("$" ++ k ++ "$") $ M.lookup k $ toMap p
107− substitute (Chunk chunk) = chunk
118+{-# DEPRECATED applyTemplateToPage "Use applyTemplate" #-}
108− substitute (Key key) = fromMaybe (missing key) $ M.lookup key map'
119+
109− substitute (Escaped) = "$"
121+--------------------------------------------------------------------------------
111-- | Apply a page as it's own template. This is often very useful to fill in
122-- | Apply a page as it's own template. This is often very useful to fill in
112-- certain keys like @$root@ and @$url@.
123-- certain keys like @$root@ and @$url@.
114applySelf :: Page String -> Page String
124applySelf :: Page String -> Page String
115−applySelf page = applyTemplate (readTemplate $ pageBody page) page
125+applySelf page = applyTemplateToPage (readTemplate $ pageBody page) page
126+{-# DEPRECATED applySelf "Use applyTemplate" #-}
129+--------------------------------------------------------------------------------
117-- | Read a template. If the extension of the file we're compiling is
130-- | Read a template. If the extension of the file we're compiling is
118-- @.hml@ or @.hamlet@, it will be considered as a Hamlet template, and parsed
131-- @.hml@ or @.hamlet@, it will be considered as a Hamlet template, and parsed
119-- as such.
132-- as such.
121templateCompiler :: Compiler () Template
133templateCompiler :: Compiler () Template
122templateCompiler = templateCompilerWith defaultHamletSettings
134templateCompiler = templateCompilerWith defaultHamletSettings
@@ -135,15 +147,9 @@ templateCompilerWith settings =
135 -- Hakyll template
147 -- Hakyll template
136 else readTemplate string
148 else readTemplate string
151+--------------------------------------------------------------------------------
138applyTemplateCompiler :: Identifier Template -- ^ Template
152applyTemplateCompiler :: Identifier Template -- ^ Template
139 -> Compiler (Page String) (Page String) -- ^ Compiler
153 -> Compiler (Page String) (Page String) -- ^ Compiler
140−applyTemplateCompiler = applyTemplateCompilerWith defaultMissingHandler
154+applyTemplateCompiler identifier = require identifier $
141−
155+ flip applyTemplateToPage
142−-- | A version of 'applyTemplateCompiler' which allows you to pass a function
143−-- which is called for a key when it is missing.
145−applyTemplateCompilerWith :: (String -> String)
146− -> Identifier Template
147− -> Compiler (Page String) (Page String)
148−applyTemplateCompilerWith missing identifier =
149− require identifier (flip $ applyTemplateWith missing)