-
Notifications
You must be signed in to change notification settings - Fork 0
/
site.hs
187 lines (159 loc) · 5.48 KB
/
site.hs
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Main where
import Hakyll
import Text.Pandoc
import Data.Maybe (catMaybes)
import Data.Monoid ((<>))
import qualified Data.Map as M
import System.FilePath (joinPath, splitPath, replaceExtension)
--------------------------------------------------------------------
-- Contexts
--------------------------------------------------------------------
postCtx :: Context String
postCtx =
dateField "date" "%B %e, %Y"
<> defaultContext
-- mathCtx :: Context String
-- mathCtx = field "mathjax" $ \item -> do
-- metadata <- getMetadata $ itemIdentifier item
-- return $ if "mathjax" `M.member` metadata
-- then "<script type=\"text/javascript\" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>"
-- else ""
blogCtx posts =
listField "posts" postCtx (return posts)
<> constField "title" "Blog - The Joy of Haskell"
<> constField "twitter-title" "The Joy of Haskell - Blog"
<> constField "twitter-description" "Updates about the book progress and other Haskell-related writings"
<> defaultContext
authorsCtx =
constField "title" "Authors - The Joy of Haskell"
<> constField "twitter-title" "The Joy of Haskell - Authors"
<> constField "twitter-description" "Julie Moronuki & Chris Martin"
<> defaultContext
indexCtx =
constField "title" "The Joy of Haskell"
<> constField "twitter-title" "The Joy of Haskell"
<> constField "twitter-description" "A complete guide to the Haskell ecosystem. For intermediate to advanced Haskellers. "
<> constField "twitter-url" "/"
<> defaultContext
--------------------------------------------------------------------
-- Rules
--------------------------------------------------------------------
static :: Rules ()
static = do
match "images/*" $ do
route idRoute
compile $ copyFileCompiler
match "css/partials/*.scss" (compile getResourceBody)
cssDeps <- makePatternDependency "css/partials/*.scss"
rulesExtraDependencies [cssDeps] $
match "css/*.scss" $ do
route (setExtension "css")
compile scssCompiler
-- match "js/*" $ do
-- route idRoute
-- compile $ copyFileCompiler
scssCompiler :: Compiler (Item String)
scssCompiler = do
input <- getResourceFilePath
output <- unixFilter "sassc" [input] ""
makeItem output
posts :: Rules ()
posts = do
match "posts/*" $ do
route $ setExtension "html"
compile $ compiler
>>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls
blog :: Rules ()
blog = do
create ["blog.html"] $ do
route idRoute
compile $ do
posts <- recentFirst =<< filterListed =<< loadAll "posts/*"
makeItem ""
>>= loadAndApplyTemplate "templates/blog.html" (blogCtx posts)
>>= loadAndApplyTemplate "templates/default.html" (blogCtx posts)
>>= relativizeUrls
authors :: Rules ()
authors = do
create ["authors.html"] $ do
route idRoute
compile $ do
makeItem ""
>>= loadAndApplyTemplate "templates/authors.html" authorsCtx
>>= loadAndApplyTemplate "templates/default.html" authorsCtx
>>= relativizeUrls
rssFeed :: Rules ()
rssFeed = do
create ["rss.xml"] $ do
route idRoute
compile $ do
posts <- fmap (take 10) . recentFirst =<< filterListed =<<
loadAllSnapshots "posts/*" "content"
renderRss feedConfig (bodyField "description" <> postCtx) posts
filterListed :: MonadMetadata m => [Item a] -> m [Item a]
filterListed =
filterM $ isListed . itemIdentifier
where
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM f xs =
catMaybes <$> traverse (\i -> (\b -> if b then Just i else Nothing) <$> f i) xs
isListed :: forall m.
MonadMetadata m
=> Identifier -- ^ Input page
-> m Bool
isListed id' =
getMetadata id' >>= \(metadata :: Metadata) ->
case lookupString "listed" metadata of
Nothing -> fail $ "There is no 'listed' attribute for " <> show id'
Just s -> parseListed s
where
parseListed :: String -> m Bool
parseListed "true" = pure True
parseListed "false" = pure False
parseListed s = fail $ "Could not parse 'listed' attribute for " <> show id' <> ": \"" <> s <> "\""
index :: Rules ()
index = do
match "index.html" $ do
route idRoute
compile $ do
getResourceBody
>>= applyAsTemplate indexCtx
>>= relativizeUrls
templates :: Rules ()
templates = match "templates/*" $ compile templateCompiler
code :: Rules ()
code = do
match "code/*" $ do
route (setExtension "html")
compile pandocCompiler
--------------------------------------------------------------------
-- Configuration
--------------------------------------------------------------------
compiler :: Compiler (Item String)
compiler = pandocCompilerWith defaultHakyllReaderOptions pandocOptions
pandocOptions :: WriterOptions
pandocOptions = defaultHakyllWriterOptions{ writerHTMLMathMethod = MathJax "" }
cfg :: Configuration
cfg = defaultConfiguration
feedConfig :: FeedConfiguration
feedConfig = FeedConfiguration
{ feedTitle = "The Joy of Haskell"
, feedDescription = "Posts about Haskell and book progress."
, feedAuthorName = "Julie Moronuki and Chris Martin"
, feedAuthorEmail = "[email protected]"
, feedRoot = "https://joyofhaskell.com"
}
main :: IO ()
main = hakyllWith cfg $ do
static
authors
posts
blog
index
templates
code
rssFeed