If you’d like to write a long posts in your Hakyll blog, you often can find
that you’d like to commit a post (or several posts), but you’re are not going to
deploy it on server. Here is my solution inspired by this
post. Now I can call
Hakyll with --with-drafts and it will use both posts and drafts
directories to collect posts data.
There are several issues I had faced with when I was solving this problem:
This is the easiest step. Hakyll uses pattern to match your blog posts to
process them. By default it’s "posts/*". In many cases it is used in
several places, so it’s a really good idea to define a variable. Patterns can
be combined using .||. operator. So we can have something like:
main = do
let postsPattern = if (draftMode)
then "posts/*" .||. "drafts/*"
else "posts/*"
hakyll $ do
match postsPattern $ do
route $ setExtension "html"
compile $ pandocCompiler
-- other routes implementationTo put result into another directory we need to change configuration and pass it to Hakyll.
main = do
let config = if (draftMode) draftConfiguration else defaultConfiguration
hakyllWith config $ do
match postsPattern $ do
-- routes implementation
-- Configuraiton for draft
draftConfiguration = defaultConfiguration {
destinationDirectory = "_draftSite"
, storeDirectory = "_draftCache"
, tmpDirectory = "_draftCache/tmp"
}So far so good, but we still haven’t detected if it’s a draft mode or not. We need to process command line arguments:
main = do
draftMode <- fmap (elem "--with-drafts") getArgs
Unfortunately, this is not enough. As I mentioned before, cmdargs does not
allow to pass unknown options, so we need to filter out all our stuff before
passing it to Hakyll. The good news is that we can process arguments and
replace them using withArgs function. So the final solution looks like
that:
checkArgs :: [String] -> (Pattern, Configuration, [String])
checkArgs args = case partition (/= "--with-drafts") args of
(_, []) -> ("posts/*", defaultConfiguration, args)
(as, _) -> ("posts/*" .||. "drafts/*", draftConfiguration, as)
main = checkArgs <$> getArgs >>=
\(postsPattern, conf, args) -> withArgs args $ hakyllWith conf $ do
match postsPattern $ do
-- routes implementation