1module Text.Hakyll.Render
13import Text.Template hiding (render)
14import qualified Data.ByteString.Lazy.Char8 as B
15import qualified Data.Map as M
16import Control.Monad (unless, liftM, foldM)
18import System.Directory (copyFile)
21import Text.Hakyll.Context (ContextManipulation)
22import Text.Hakyll.Page
23import Text.Hakyll.Renderable
24import Text.Hakyll.File
25import Text.Hakyll.CompressCSS
27-- | Execute an IO action only when the cache is invalid.
28depends :: FilePath -- ^ File to be rendered or created.
29 -> [FilePath] -- ^ Files the render depends on.
30 -> IO () -- ^ IO action to execute when the file is out of date.
32depends file dependencies action = do
33 valid <- isCacheValid (toDestination file) dependencies
38 => FilePath -- ^ Template to use for rendering.
39 -> a -- ^ Renderable object to render with given template.
40 -> IO Page -- ^ The body of the result will contain the render.
43-- | Render to a Page. This function allows you to manipulate the context
45renderWith :: 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.
50renderWith manipulation templatePath renderable = do
51 handle <- openFile templatePath ReadMode
52 templateString <- liftM B.pack $ hGetContents handle
53 seq templateString $ hClose handle
54 context <- liftM manipulation $ toContext renderable
55 let body = substitute templateString context
56 return $ fromContext (M.insert (B.pack "body") body context)
58-- | Render each renderable with the given template, then concatenate the
60renderAndConcat :: Renderable a => FilePath -> [a] -> IO B.ByteString
61renderAndConcat = renderAndConcatWith id
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".
66renderAndConcatWith :: Renderable a
67 => ContextManipulation
71renderAndConcatWith manipulation templatePath renderables =
72 foldM concatRender' B.empty renderables
73 where concatRender' :: Renderable a => B.ByteString -> a -> IO B.ByteString
74 concatRender' chunk renderable = do
75 rendered <- renderWith manipulation templatePath renderable
76 let body = getBody rendered
77 return $ B.append chunk $ body
79-- | Chain a render action for a page with a number of templates. This will
80-- also write the result to the site destination. This is the preferred way
81-- to do general rendering.
82renderChain :: Renderable a => [FilePath] -> a -> IO ()
83renderChain = renderChainWith id
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.
87renderChainWith :: Renderable a
88 => ContextManipulation -> [FilePath] -> a -> IO ()
89renderChainWith manipulation templates renderable =
90 depends (getURL renderable) (getDependencies renderable ++ templates) $
91 do initialPage <- liftM manipulation $ toContext renderable
92 result <- foldM (flip render) (fromContext initialPage) templates
95-- | Mark a certain file as static, so it will just be copied when the site is
97static :: FilePath -> IO ()
98static source = depends destination [source]
99 (makeDirectories destination >> copyFile source destination)
100 where destination = toDestination source
102-- | Render a css file, compressing it.
103css :: FilePath -> IO ()
104css source = depends destination [source] css'
105 where destination = toDestination source
106 css' = do h <- openFile source ReadMode
107 contents <- hGetContents h
108 makeDirectories destination
109 writeFile destination (compressCSS contents)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list