diff options
| -rw-r--r-- | mysite.cabal | 8 | ||||
| -rw-r--r-- | site.hs | 111 | ||||
| -rw-r--r-- | src/Site/Compilers.hs | 34 | ||||
| -rw-r--r-- | src/Site/Content.hs | 32 | ||||
| -rw-r--r-- | src/Site/Contexts.hs | 49 | ||||
| -rw-r--r-- | src/Site/Rules.hs | 41 | ||||
| -rw-r--r-- | src/site.hs | 67 |
7 files changed, 231 insertions, 111 deletions
diff --git a/mysite.cabal b/mysite.cabal index 6338acb..2885ebe 100644 --- a/mysite.cabal +++ b/mysite.cabal @@ -4,8 +4,16 @@ build-type: Simple cabal-version: >= 1.24.0 executable site + hs-source-dirs: src/ main-is: site.hs build-depends: base == 4.* , hakyll == 4.12.* + , lens == 4.16.* + + other-modules: Site.Compilers + Site.Content + Site.Contexts + Site.Rules + ghc-options: -threaded default-language: Haskell2010 diff --git a/site.hs b/site.hs deleted file mode 100644 index 6f3ffa0..0000000 --- a/site.hs +++ /dev/null @@ -1,111 +0,0 @@ --------------------------------------------------------------------------------- -{-# LANGUAGE OverloadedStrings #-} -import Data.Monoid ((<>)) -import Hakyll - - --------------------------------------------------------------------------------- -main :: IO () -main = hakyll $ do - match "img/*" $ do - route idRoute - compile copyFileCompiler - - match "css/*" $ do - route idRoute - compile compressCssCompiler - - match "log/*.org" $ do - route $ setExtension "html" - compile $ pandocCompiler - >>= loadAndApplyTemplate "templates/post.html" postCtx - >>= relativizeUrls - - create ["log/index.html"] $ do - route idRoute - compile $ do - makeItem "" - >>= loadAndApplyTemplate "templates/post-list.html" postForArchiveCtx - >>= loadAndApplyTemplate "templates/post.html" archiveCtx - >>= relativizeUrls - - match "gsoc/*.org" $ do - route $ setExtension "html" - compile $ pandocCompiler - >>= loadAndApplyTemplate "templates/post.html" postCtx - >>= relativizeUrls - - create ["gsoc/index.html"] $ do - route idRoute - compile $ do - makeItem "" - >>= loadAndApplyTemplate "templates/post-list.html" gsocPostForArchiveCtx - >>= loadAndApplyTemplate "templates/post.html" gsocArchiveCtx - >>= relativizeUrls - - match "article/**" $ do - route idRoute - compile getResourceBody - - match "index.html" $ do - route idRoute - compile $ do - getResourceBody - >>= applyAsTemplate indexCtx - >>= relativizeUrls - - match "templates/*" $ compile templateBodyCompiler - - --------------------------------------------------------------------------------- -gsocPosts :: Compiler [Item String] -gsocPosts = recentFirst =<< loadAll "gsoc/*.org" - -posts :: Compiler [Item String] -posts = recentFirst =<< loadAll "log/*.org" - -articles :: Compiler [Item String] -articles = loadAll "article/**" - -recentPosts :: Compiler [Item String] -recentPosts = (take 4) <$> posts - -recentArticles :: Compiler [Item String] -recentArticles = (take 4) <$> articles - -indexCtx :: Context String -indexCtx = - listField "articles" defaultContext recentArticles - <> listField "rposts" defaultContext recentPosts - <> constField "essays" "Soon" - <> constField "title" "Home" - <> defaultContext - -archiveCtx :: Context String -archiveCtx = - constField "title" "archive of log posts" - <> defaultContext - -gsocArchiveCtx :: Context String -gsocArchiveCtx = - constField "title" "archive of my GSoC reports." - <> defaultContext - -postCtx :: Context String -postCtx = - dateField "date" "%B %e, %Y" <> defaultContext - -postForArchiveCtx :: Context String -postForArchiveCtx = - listField "posts" dateForArchiveCtx posts - <> defaultContext - -gsocPostForArchiveCtx :: Context String -gsocPostForArchiveCtx = - listField "posts" dateForArchiveCtx gsocPosts - <> defaultContext - -dateForArchiveCtx :: Context String -dateForArchiveCtx = - dateField "date" "%d %b %Y" <> defaultContext - diff --git a/src/Site/Compilers.hs b/src/Site/Compilers.hs new file mode 100644 index 0000000..dbb943b --- /dev/null +++ b/src/Site/Compilers.hs @@ -0,0 +1,34 @@ +module Site.Compilers + ( gsocPosts + , posts + , articles + , recentPosts + , recentArticles + ) +where + +import Hakyll ( Compiler + , Item + , loadAll + , recentFirst + , Pattern + , fromGlob + ) + +loadAllRecentFirst :: String -> Compiler [Item String] +loadAllRecentFirst glob = recentFirst =<< loadAll (fromGlob glob) + +gsocPosts :: Compiler [Item String] +gsocPosts = loadAllRecentFirst "gsoc/*.org" + +posts :: Compiler [Item String] +posts = loadAllRecentFirst "log/*.org" + +articles :: Compiler [Item String] +articles = loadAll (fromGlob "article/**") + +recentPosts :: Compiler [Item String] +recentPosts = take 4 <$> posts + +recentArticles :: Compiler [Item String] +recentArticles = take 4 <$> articles diff --git a/src/Site/Content.hs b/src/Site/Content.hs new file mode 100644 index 0000000..2f82484 --- /dev/null +++ b/src/Site/Content.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE TemplateHaskell #-} +module Site.Content + ( Content(..) + , contentPattern + , contentPaths + , contentRoute + , contentContext + , contentTemplate + , contentIndexContext + , contentIndexTemplate + ) +where + +import Control.Lens +import Hakyll ( Pattern + , Context + , Routes + , Identifier + ) + +-- the information for a kind of content, e.g. notes +data Content = Content { + _contentPattern :: Pattern + , _contentPaths :: [Identifier] + , _contentRoute :: Routes + , _contentContext :: Hakyll.Context String + , _contentTemplate :: String + , _contentIndexContext :: Hakyll.Context String + , _contentIndexTemplate :: String + } + +makeLenses ''Content diff --git a/src/Site/Contexts.hs b/src/Site/Contexts.hs new file mode 100644 index 0000000..f383444 --- /dev/null +++ b/src/Site/Contexts.hs @@ -0,0 +1,49 @@ +module Site.Contexts + ( indexCtx + , archiveCtx + , logArchiveCtx + , gsocArchiveCtx + , postCtx + , postForArchiveCtx + , gsocPostForArchiveCtx + , dateForArchiveCtx + ) +where +import Data.Monoid ( (<>) ) +import Site.Compilers +import Hakyll ( Context + , defaultContext + , constField + , dateField + , listField + ) + +indexCtx :: Context String +indexCtx = + listField "articles" defaultContext recentArticles + <> listField "rposts" defaultContext recentPosts + <> constField "essays" "Soon" + <> constField "title" "Home" + <> defaultContext + +archiveCtx :: String -> Context String +archiveCtx title = constField "title" title <> defaultContext + +logArchiveCtx :: Context String +logArchiveCtx = archiveCtx "archive of log posts" + +gsocArchiveCtx :: Context String +gsocArchiveCtx = archiveCtx "archive of my GSoC reports." + +postCtx :: Context String +postCtx = dateField "date" "%B %e, %Y" <> defaultContext + +postForArchiveCtx :: Context String +postForArchiveCtx = listField "posts" dateForArchiveCtx posts <> defaultContext + +gsocPostForArchiveCtx :: Context String +gsocPostForArchiveCtx = + listField "posts" dateForArchiveCtx gsocPosts <> defaultContext + +dateForArchiveCtx :: Context String +dateForArchiveCtx = dateField "date" "%d %b %Y" <> defaultContext diff --git a/src/Site/Rules.hs b/src/Site/Rules.hs new file mode 100644 index 0000000..731d6d9 --- /dev/null +++ b/src/Site/Rules.hs @@ -0,0 +1,41 @@ +module Site.Rules + ( indexRules + , contentRules + ) +where +import Site.Content +import Hakyll + +indexRules :: Content -> Rules () +indexRules content = create paths $ do + route routeConfig + compile + $ makeItem "" + >>= loadAndApplyTemplate itemListTemplate listContext + >>= loadAndApplyTemplate itemTemplate context + >>= relativizeUrls + where + paths = _contentPaths content + routeConfig = _contentRoute content + listTemplate = _contentIndexTemplate content + template = _contentTemplate content + context = _contentContext content + listContext = _contentIndexContext content + itemListTemplate = + fromFilePath $ "templates/" ++ listTemplate ++ ".html" + itemTemplate = fromFilePath $ "templates/" ++ template ++ ".html" + + +contentRules :: Content -> Rules () +contentRules content = match glob $ do + route routeConfig + compile + $ pandocCompiler + >>= loadAndApplyTemplate itemTemplate context + >>= relativizeUrls + where + glob = _contentPattern content + routeConfig = _contentRoute content + template = _contentTemplate content + context = _contentContext content + itemTemplate = fromFilePath $ "templates/" ++ template ++ ".html" diff --git a/src/site.hs b/src/site.hs new file mode 100644 index 0000000..be4af68 --- /dev/null +++ b/src/site.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE OverloadedStrings #-} +import Data.Monoid ( (<>) ) +import Hakyll +import Control.Lens +import Site.Rules ( indexRules + , contentRules + ) +import Site.Contexts +import Site.Content + +main :: IO () +main = hakyll $ do + match "img/*" $ do + route idRoute + compile copyFileCompiler + + match "css/*" $ do + route idRoute + compile compressCssCompiler + + match "article/**" $ do + route idRoute + compile getResourceBody + + match "index.html" $ do + route idRoute + compile + $ getResourceBody + >>= applyAsTemplate indexCtx + >>= relativizeUrls + + match "templates/*" $ compile templateBodyCompiler + + let log = Content { _contentPattern = "log/*.org" + , _contentPaths = [] + , _contentRoute = setExtension "html" + , _contentTemplate = "post" + , _contentIndexTemplate = "post" + , _contentContext = postCtx + , _contentIndexContext = postCtx + } + + logIndex = Content + { _contentPaths = [fromFilePath "log/index.html"] + , _contentPattern = "" + , _contentRoute = idRoute + , _contentIndexTemplate = "post-list" + , _contentTemplate = "post" + , _contentContext = logArchiveCtx + , _contentIndexContext = postForArchiveCtx + } + + gsoc = log & contentPattern .~ "gsoc/*.org" + + gsocIndex = + logIndex + & contentPaths + .~ [fromFilePath "gsoc/index.html"] + & contentContext + .~ gsocArchiveCtx + & contentIndexContext + .~ gsocPostForArchiveCtx + + contentRules log + indexRules logIndex + contentRules gsoc + indexRules gsocIndex |
