1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
-- | Module containing rendering functions. All these functions are used to
-- render files to the @_site@ directory.
module Text.Hakyll.Render
( depends
, render
, renderWith
, renderAndConcat
, renderAndConcatWith
, renderChain
, renderChainWith
, static
, css
) where
import Control.Monad (unless)
import Control.Monad.Reader (liftIO)
import System.Directory (copyFile)
import Text.Hakyll.Hakyll (Hakyll)
import Text.Hakyll.Context (ContextManipulation)
import Text.Hakyll.Page
import Text.Hakyll.Renderable
import Text.Hakyll.File
import Text.Hakyll.Internal.Template (readTemplate)
import Text.Hakyll.Internal.CompressCss
import Text.Hakyll.Internal.Render
-- | Execute an IO action only when the cache is invalid.
depends :: FilePath -- ^ File to be rendered or created.
-> [FilePath] -- ^ Files the render depends on.
-> Hakyll () -- ^ IO action to execute when the file is out of date.
-> Hakyll ()
depends file dependencies action = do
destination <- toDestination file
valid <- isFileMoreRecent destination dependencies
unless valid action
-- | Render to a Page.
render :: Renderable a
=> FilePath -- ^ Template to use for rendering.
-> a -- ^ Renderable object to render with given template.
-> Hakyll Page -- ^ The body of the result will contain the render.
render = renderWith id
-- | Render to a Page. This function allows you to manipulate the context
-- first.
renderWith :: Renderable a
=> ContextManipulation -- ^ Manipulation to apply on the context.
-> FilePath -- ^ Template to use for rendering.
-> a -- ^ Renderable object to render with given template.
-> Hakyll Page -- ^ The body of the result will contain the render.
renderWith manipulation templatePath renderable = do
template <- readTemplate templatePath
context <- toContext renderable
return $ fromContext $ pureRenderWith manipulation template context
-- | Render each renderable with the given templates, then concatenate the
-- result. So, basically this function:
--
-- * Takes every renderable.
--
-- * Renders every renderable with all given templates. This is comparable
-- with a renderChain action.
--
-- * Concatenates the result.
--
renderAndConcat :: Renderable a
=> [FilePath] -- ^ Templates to apply on every renderable.
-> [a] -- ^ Renderables to render.
-> Hakyll String
renderAndConcat = renderAndConcatWith id
-- | Render each renderable with the given templates, then concatenate the
-- result. This function allows you to specify a @ContextManipulation@ to
-- apply on every @Renderable@.
renderAndConcatWith :: Renderable a
=> ContextManipulation
-> [FilePath]
-> [a]
-> Hakyll String
renderAndConcatWith manipulation templatePaths renderables = do
templates <- mapM readTemplate templatePaths
contexts <- mapM toContext renderables
return $ pureRenderAndConcatWith manipulation templates contexts
-- | Chain a render action for a page with a number of templates. This will
-- also write the result to the site destination. This is the preferred way
-- to do general rendering.
--
-- > renderChain [ "templates/notice.html"
-- > , "templates/default.html"
-- > ] $ createPagePath "warning.html"
--
-- This code will first render @warning.html@ using @templates/notice.html@,
-- and will then render the result with @templates/default.html@.
renderChain :: Renderable a => [FilePath] -> a -> Hakyll ()
renderChain = renderChainWith id
-- | A more custom render chain that allows you to specify a
-- @ContextManipulation@ which to apply on the context when it is read first.
renderChainWith :: Renderable a
=> ContextManipulation -> [FilePath] -> a -> Hakyll ()
renderChainWith manipulation templatePaths renderable = do
url <- getUrl renderable
depends url dependencies render'
where
dependencies = getDependencies renderable ++ templatePaths
render' = do
templates <- mapM readTemplate templatePaths
context <- toContext renderable
let result = pureRenderChainWith manipulation templates context
writePage $ fromContext result
-- | Mark a certain file as static, so it will just be copied when the site is
-- generated.
static :: FilePath -> Hakyll ()
static source = do destination <- toDestination source
depends destination [source] (action destination)
where
action destination = do makeDirectories destination
liftIO $ copyFile source destination
-- | Render a css file, compressing it.
css :: FilePath -> Hakyll ()
css source = do destination <- toDestination source
depends destination [source] (css' destination)
where
css' destination = do contents <- liftIO $ readFile source
makeDirectories destination
liftIO $ writeFile destination (compressCss contents)
|