213 lines
6.8 KiB
Haskell
213 lines
6.8 KiB
Haskell
--------------------------------------------------------------------------------
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
import Hakyll
|
|
import Data.Monoid ((<>))
|
|
import Data.List
|
|
import Data.Maybe (fromMaybe)
|
|
import Data.Time.Format (parseTimeM, defaultTimeLocale)
|
|
import Data.Time.Clock (UTCTime)
|
|
import System.FilePath (takeFileName)
|
|
import Network.HTTP.Base (urlEncode)
|
|
import Control.Monad (liftM)
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
main :: IO ()
|
|
main =
|
|
|
|
hakyllWith config $ do
|
|
|
|
match "templates/*" $ compile templateCompiler
|
|
|
|
--copy fonts, images etc.
|
|
match
|
|
( "site/font/**"
|
|
.||. "site/images/**"
|
|
.||. "site/vids/**"
|
|
.||. "site/humans.txt"
|
|
.||. "site/8ADADB98780B5BAF.asc"
|
|
.||. "site/robots.txt"
|
|
.||. "site/keybase.txt"
|
|
) $ do
|
|
route myRoute
|
|
compile copyFileCompiler
|
|
|
|
match "site/css/*" $ do
|
|
route myRoute
|
|
compile compressCssCompiler
|
|
|
|
-- Build tags
|
|
tags <- buildTags "site/posts/*.md" (fromCapture "tags/*.html")
|
|
|
|
--build tagcloud
|
|
let baseCtx = tagCloudField "tagCloud" 100 100 tags <>
|
|
defaultContext
|
|
|
|
match "site/index.md" $ do
|
|
route $ myRoute `composeRoutes` setExtension "html"
|
|
compile $ do
|
|
posts <- fmap (take 6) . recentFirst =<< loadAll "site/posts/*"
|
|
let indexCtx = listField "posts" (postCtx tags) (return posts) <>
|
|
constField "title" "Home" <>
|
|
defaultContext
|
|
getResourceBody
|
|
>>= applyAsTemplate indexCtx
|
|
>>= renderPandoc
|
|
>>= loadAndApplyTemplate "templates/default.html" baseCtx
|
|
-- >>= relativizeUrls
|
|
|
|
match (fromList
|
|
[ "site/about.md"
|
|
, "site/imprint.md"
|
|
, "site/contact.md"
|
|
]) $ do
|
|
route $ myRoute `composeRoutes` setExtension "html"
|
|
compile $ pandocCompiler
|
|
>>= loadAndApplyTemplate "templates/default.html" baseCtx
|
|
-- >>= relativizeUrls
|
|
|
|
match "site/404.md" $ do
|
|
route $ myRoute `composeRoutes` setExtension "html"
|
|
compile $ pandocCompiler
|
|
>>= loadAndApplyTemplate "templates/default.html" baseCtx
|
|
|
|
is <- sortIdentifiersByDate <$> getMatches "site/posts/*.md"
|
|
|
|
pages <- buildPaginateWith
|
|
(liftM (paginateEvery 1) . sortRecentFirst)
|
|
"site/posts/*.md"
|
|
(\n -> is !! (n - 1))
|
|
|
|
paginateRules pages $ \num _ -> do
|
|
route $ myRoute `composeRoutes` setExtension "html"
|
|
compile $ do
|
|
ident <- getUnderlying
|
|
title <- getMetadataField' ident "title"
|
|
url <- return . fromMaybe "" =<< getRoute ident
|
|
compiled <- getResourceBody >>= renderPandoc
|
|
let pageCtx = paginateContext pages num
|
|
let flattrCtx = constField "enctitle" (urlEncode title) <>
|
|
constField "encurl" (urlEncode $ "https://nek0.eu/" ++ url)
|
|
let ctx = (postCtx tags) <> pageCtx <> flattrCtx <> baseCtx
|
|
full <- loadAndApplyTemplate "templates/post.html" ctx compiled
|
|
_ <- saveSnapshot "content" compiled
|
|
loadAndApplyTemplate "templates/default.html" (baseCtx <> ctx) full
|
|
|
|
-- Post tags
|
|
tagsRules tags $ \tag pattern -> do
|
|
let title = "Posts tagged " ++ tag ++ ":"
|
|
-- Copied from posts, need to refactor
|
|
route myRoute
|
|
compile $ do
|
|
posts <- recentFirst =<< loadAll pattern
|
|
let ctx = constField "title" title <>
|
|
listField "posts" (postCtx tags) (return posts) <>
|
|
baseCtx
|
|
makeItem ""
|
|
>>= loadAndApplyTemplate "templates/post-list.html" ctx
|
|
>>= loadAndApplyTemplate "templates/default.html" ctx
|
|
>>= relativizeUrls
|
|
|
|
create ["archive.html"] $ do
|
|
route idRoute
|
|
compile $ do
|
|
posts <- recentFirst =<< loadAll "site/posts/*"
|
|
let archiveCtx = listField "posts" (postCtx tags) (return posts) <>
|
|
constField "title" "Archives" <>
|
|
baseCtx
|
|
makeItem ""
|
|
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
|
|
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
|
|
-- >>= relativizeUrls
|
|
|
|
-- feeds
|
|
|
|
create ["atom.xml"] $ do
|
|
route idRoute
|
|
compile $ do
|
|
loadAllSnapshots "site/posts/*.md" "content"
|
|
>>= recentFirst
|
|
>>= renderAtom feedConf feedCtx
|
|
|
|
create ["rss.xml"] $ do
|
|
route idRoute
|
|
compile $ do
|
|
loadAllSnapshots "site/posts/*.md" "content"
|
|
>>= recentFirst
|
|
>>= renderRss feedConf feedCtx
|
|
|
|
create ["sitemap.xml"] $ do
|
|
route idRoute
|
|
compile $ do
|
|
rposts <- loadAll "site/**/*.md"
|
|
rsites <- loadAll "site/*.md"
|
|
-- rtxts <- loadAll "site/*.txt"
|
|
-- rascs <- loadAll "site/*.asc"
|
|
let sites = return (rposts ++ rsites)
|
|
let sitemapCtx = mconcat
|
|
[ listField "entries"
|
|
(postCtx tags <> constField "host" "https://nek0.eu/")
|
|
sites
|
|
, constField "host" "https://nek0.eu/"
|
|
, defaultContext
|
|
]
|
|
makeItem ""
|
|
>>= loadAndApplyTemplate "templates/sitemap.xml" sitemapCtx
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
sortIdentifiersByDate :: [Identifier] -> [Identifier]
|
|
sortIdentifiersByDate =
|
|
sortBy byDate
|
|
where
|
|
byDate id1 id2 =
|
|
let fn1 = takeFileName $ toFilePath id1
|
|
fn2 = takeFileName $ toFilePath id2
|
|
parseTime' fn = parseTimeM True defaultTimeLocale "%Y-%m-%d" $
|
|
intercalate "-" $ take 3 $ splitAll "-" fn
|
|
in compare
|
|
(parseTime' fn1 :: Maybe UTCTime)
|
|
(parseTime' fn2 :: Maybe UTCTime)
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
postCtx :: Tags -> Context String
|
|
postCtx tags = mconcat
|
|
[ modificationTimeField "mtime" "%U"
|
|
, dateField "date" "%B %e, %Y"
|
|
, dateField "datetime" "%F"
|
|
, tagsField "tags" tags
|
|
, defaultContext
|
|
]
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
feedCtx :: Context String
|
|
feedCtx = mconcat
|
|
[ bodyField "description"
|
|
, defaultContext
|
|
]
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
feedConf :: FeedConfiguration
|
|
feedConf = FeedConfiguration
|
|
{ feedTitle = "nek0's blog"
|
|
, feedDescription = "Random things"
|
|
, feedAuthorName = "nek0"
|
|
, feedAuthorEmail = "nek0@nek0.eu"
|
|
, feedRoot = "https://nek0.eu"
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
config :: Configuration
|
|
config = defaultConfiguration
|
|
{ deployCommand = "rsync --del --checksum -ave 'ssh -p 5555' \\_site/* nek0@nek0.eu:/home/nek0/blog"
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
myRoute :: Routes
|
|
myRoute = gsubRoute "site/" (const "")
|