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:
= do
main let postsPattern = if (draftMode)
then "posts/*" .||. "drafts/*"
else "posts/*"
$ do
hakyll $ do
match postsPattern $ setExtension "html"
route $ pandocCompiler
compile -- other routes implementation
To put result into another directory we need to change configuration and pass it to Hakyll.
= do
main let config = if (draftMode) draftConfiguration else defaultConfiguration
$ do
hakyllWith config $ do
match postsPattern -- routes implementation
-- Configuraiton for draft
= defaultConfiguration {
draftConfiguration = "_draftSite"
destinationDirectory = "_draftCache"
, storeDirectory = "_draftCache/tmp"
, tmpDirectory }
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])
= case partition (/= "--with-drafts") args of
checkArgs args -> ("posts/*", defaultConfiguration, args)
(_, []) -> ("posts/*" .||. "drafts/*", draftConfiguration, as)
(as, _)
= checkArgs <$> getArgs >>=
main -> withArgs args $ hakyllWith conf $ do
\(postsPattern, conf, args) $ do
match postsPattern -- routes implementation