@@ -1,8 +1,11 @@
11module Text.Hakyll.Render
22 ( depends
33 , render
4+ , renderWith
45 , renderAndConcat
6+ , renderAndConcatWith
57 , renderChain
8+ , renderChainWith
69 , static
710 , css
811 ) where
@@ -15,6 +18,7 @@ import Control.Monad (unless, liftM, foldM)
1518import System.Directory (copyFile)
1619import System.IO
1720
21+import Text.Hakyll.Context (ContextManipulation)
1822import Text.Hakyll.Page
1923import Text.Hakyll.Renderable
2024import Text.Hakyll.File
@@ -34,21 +38,41 @@ render :: Renderable a
3438 => FilePath -- ^ Template to use for rendering.
3539 -> a -- ^ Renderable object to render with given template.
3640 -> IO Page -- ^ The body of the result will contain the render.
37−render templatePath renderable = do
41+render = renderWith id
42+
43+-- | Render to a Page. This function allows you to manipulate the context
44+-- first.
45+renderWith :: Renderable a
46+ => ContextManipulation -- ^ Manipulation to apply on the context.
47+ -> FilePath -- ^ Template to use for rendering.
48+ -> a -- ^ Renderable object to render with given template.
49+ -> IO Page -- ^ The body of the result will contain the render.
50+renderWith manipulation templatePath renderable = do
3851 handle <- openFile templatePath ReadMode
3952 templateString <- liftM B.pack $ hGetContents handle
4053 seq templateString $ hClose handle
41− context <- toContext renderable
54+ context <- liftM manipulation $ toContext renderable
4255 let body = substitute templateString context
4356 return $ fromContext (M.insert (B.pack "body") body context)
4457
4558-- | Render each renderable with the given template, then concatenate the
4659-- result.
4760renderAndConcat :: Renderable a => FilePath -> [a] -> IO B.ByteString
48−renderAndConcat templatePath renderables = foldM concatRender' B.empty renderables
61+renderAndConcat = renderAndConcatWith id
62+
63+-- | Render each renderable with the given template, then concatenate the
64+-- result. This function allows you to specify a "ContextManipulation" to
65+-- apply on every "Renderable".
66+renderAndConcatWith :: Renderable a
67+ => ContextManipulation
68+ -> FilePath
69+ -> [a]
70+ -> IO B.ByteString
71+renderAndConcatWith manipulation templatePath renderables =
72+ foldM concatRender' B.empty renderables
4973 where concatRender' :: Renderable a => B.ByteString -> a -> IO B.ByteString
5074 concatRender' chunk renderable = do
51− rendered <- render templatePath renderable
75+ rendered <- renderWith manipulation templatePath renderable
5276 let body = getBody rendered
5377 return $ B.append chunk $ body
5478
@@ -56,9 +80,15 @@ renderAndConcat templatePath renderables = foldM concatRender' B.empty renderabl
5680-- also write the result to the site destination. This is the preferred way
5781-- to do general rendering.
5882renderChain :: Renderable a => [FilePath] -> a -> IO ()
59−renderChain templates renderable =
83+renderChain = renderChainWith id
84+
85+-- | A more custom render chain that allows you to specify a
86+-- "ContextManipulation" which to apply on the context when it is read first.
87+renderChainWith :: Renderable a
88+ => ContextManipulation -> [FilePath] -> a -> IO ()
89+renderChainWith manipulation templates renderable =
6090 depends (getURL renderable) (getDependencies renderable ++ templates) $
61− do initialPage <- toContext renderable
91+ do initialPage <- liftM manipulation $ toContext renderable
6292 result <- foldM (flip render) (fromContext initialPage) templates
6393 writePage result
6494