Posts are generated but not the index
H6SY4TCOYCGKYC77SWG4EUEW225SPJT4JGG4YEM2Z4JI2WHWVPYAC
import Control.Monad (forM_)
import Data.Maybe (fromMaybe)
import Hakyll
import qualified Data.Text as T
import qualified Data.Text.Slugger as Slugger
import Text.Pandoc
( Extension (Ext_fenced_code_attributes, Ext_footnotes, Ext_gfm_auto_identifiers, Ext_implicit_header_references, Ext_smart),
Extensions,
ReaderOptions,
WriterOptions (writerHighlightStyle),
extensionsFromList,
githubMarkdownExtensions,
readerExtensions,
writerExtensions,
)
import Text.Pandoc.Highlighting (Style, breezeDark, styleToCss)
import Data.Monoid (mappend)
import Hakyll
-- CONFIG
root :: String
root =
"https://alexis.praga.free.fr"
siteName :: String
siteName =
"Armadillo"
config :: Configuration
config =
defaultConfiguration
{ destinationDirectory = "dist"
, ignoreFile = const False
, previewHost = "127.0.0.1"
, previewPort = 8000
, providerDirectory = "."
, storeDirectory = "blog/_cache"
, tmpDirectory = "blog/_tmp"
}
--------------------------------------------------------------------------------
-- BUILD
main = hakyllWith config $ do
forM_
[ "CNAME"
, "favicon.ico"
, "robots.txt"
, "_config.yml"
, "images/*"
, "js/*"
, "fonts/*"
]
$ \f -> match f $ do
route idRoute
compile copyFileCompiler
main = hakyll $ do
match "images/*" $ do
route idRoute
compile copyFileCompiler
match "posts/*" $ do
let ctx = constField "type" "article" <> postCtx
-- match (fromList ["about.rst", "contact.markdown"]) $ do
-- route $ setExtension "html"
-- compile $ pandocCompiler
-- >>= loadAndApplyTemplate "templates/default.html" defaultContext
-- >>= relativizeUrls
route $ metadataRoute titleRoute
compile $
pandocCompilerCustom
>>= loadAndApplyTemplate "templates/post.html" ctx
>>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/default.html" ctx
match "posts/*" $ do
route $ setExtension "html"
compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls
match "index.html" $ do
route idRoute
compile $ do
posts <- recentFirst =<< loadAll "posts/*"
-- create ["archive.html"] $ do
-- route idRoute
-- compile $ do
-- posts <- recentFirst =<< loadAll "posts/*"
-- let archiveCtx =
-- listField "posts" postCtx (return posts) `mappend`
-- constField "title" "Archives" `mappend`
-- defaultContext
let indexCtx =
listField "posts" postCtx (return posts)
<> constField "root" root
<> constField "siteName" siteName
<> defaultContext
-- makeItem ""
-- >>= loadAndApplyTemplate "templates/archive.html" archiveCtx
-- >>= loadAndApplyTemplate "templates/default.html" archiveCtx
-- >>= relativizeUrls
makeItem ("" :: String)
>>= loadAndApplyTemplate "templates/sitemap.xml" sitemapCtx
create ["rss.xml"] $ do
route idRoute
compile (feedCompiler renderRss)
create ["atom.xml"] $ do
route idRoute
compile (feedCompiler renderAtom)
create ["css/code.css"] $ do
route idRoute
compile (makeStyle pandocHighlightStyle)
--------------------------------------------------------------------------------
-- COMPILER HELPERS
constField "root" root
<> constField "siteName" siteName
<> dateField "date" "%Y-%m-%d"
<> defaultContext
titleCtx :: Context String
titleCtx =
field "title" updatedTitle
--------------------------------------------------------------------------------
-- TITLE HELPERS
replaceAmp :: String -> String
replaceAmp =
replaceAll "&" (const "&")
replaceTitleAmp :: Metadata -> String
replaceTitleAmp =
replaceAmp . safeTitle
safeTitle :: Metadata -> String
safeTitle =
fromMaybe "no title" . lookupString "title"
updatedTitle :: Item a -> Compiler String
updatedTitle =
fmap replaceTitleAmp . getMetadata . itemIdentifier
--------------------------------------------------------------------------------
-- PANDOC
pandocCompilerCustom :: Compiler (Item String)
pandocCompilerCustom =
pandocCompilerWith pandocReaderOpts pandocWriterOpts
pandocExtensionsCustom :: Extensions
pandocExtensionsCustom =
githubMarkdownExtensions
<> extensionsFromList
[ Ext_fenced_code_attributes
, Ext_gfm_auto_identifiers
, Ext_implicit_header_references
, Ext_smart
, Ext_footnotes
]
pandocReaderOpts :: ReaderOptions
pandocReaderOpts =
defaultHakyllReaderOptions
{ readerExtensions = pandocExtensionsCustom
}
pandocWriterOpts :: WriterOptions
pandocWriterOpts =
defaultHakyllWriterOptions
{ writerExtensions = pandocExtensionsCustom
, writerHighlightStyle = Just pandocHighlightStyle
}
pandocHighlightStyle :: Style
pandocHighlightStyle =
breezeDark -- https://hackage.haskell.org/package/pandoc/docs/Text-Pandoc-Highlighting.html
-- FEEDS
type FeedRenderer =
FeedConfiguration ->
Context String ->
[Item String] ->
Compiler (Item String)
feedCompiler :: FeedRenderer -> Compiler (Item String)
feedCompiler renderer =
renderer feedConfiguration feedCtx
=<< recentFirst
=<< loadAllSnapshots "posts/*" "content"
feedConfiguration :: FeedConfiguration
feedConfiguration =
FeedConfiguration
{ feedTitle = "My Site"
, feedDescription = "My Site Description"
, feedAuthorName = "My Name"
, feedAuthorEmail = "me@myemail.com"
, feedRoot = root
}
--------------------------------------------------------------------------------
-- CUSTOM ROUTE
getTitleFromMeta :: Metadata -> String
getTitleFromMeta =
fromMaybe "no title" . lookupString "title"
fileNameFromTitle :: Metadata -> FilePath
fileNameFromTitle =
T.unpack . (`T.append` ".html") . Slugger.toSlug . T.pack . getTitleFromMeta
titleRoute :: Metadata -> Routes
titleRoute =
constRoute . fileNameFromTitle
dateField "date" "%B %e, %Y" `mappend`
defaultContext
# structure
- [blog](blog/) contains the rules for Hakyll to generate the static content
- [posts](posts/) contains a list of post in org-mode
Install dependancies and build the executable , and generate the site with
nix run . build
Make it local :
nix run . watch
# Structure
- [](blog) contains the rules for Hakyll to generate the static content
- [](posts) contains a list of post in org-mode. Blog posts need a date in their title !
- Nix configuration :
- [](flake.nix) : create an application to run the blog
- [](haskell-overlay.nix) : define a derivation to build the blog