Adding `published` to Hakyll Posts
Last week I deployed the blog and published by mistake a post that I was keeping for the future:
Damn, I inadvertently published the post that was supposed to be out on Monday 😅
— Riccardo Odone (@RiccardoOdone) May 8, 2020
I guess that was just a matter of time cause I always keep some unpublished posts around. Up until now, I was doing some hacky manual git stuff to schedule them. Not anymore!
I added support for an additional published
field in the metadata of each post. The scaffolding script now adds published: false
by default.
The core of the change resides in site.hs
:
- match "posts/*" $ do
+ matchMetadata "posts/*" isPublished $ do
In particular, instead of compiling all posts, it only takes the “published” ones. A post is considered published if
- it does not have a
published
metadata field or published
istrue
.
I could have enforced all posts to have a published
field and skip 1. but I was too lazy to retrofit that 😅
Here’s the implementation:
isPublished :: Metadata -> Bool
= maybe True (== "true") . lookupString "published" isPublished
I actually did one step more and decided to consider all posts published when a HAKYLL_ENV
env variable is set to development
:
<- getEnvironment
env $ do
hakyll "posts/*" (isDevelopmentOrPublished env) $ do
matchMetadata -- ...
isDevelopmentOrPublished :: [(String, String)] -> Metadata -> Bool
= isDevelopmentEnv || isPublished
isDevelopmentOrPublished env metadata where
= lookup "HAKYLL_ENV" env == Just "development"
isDevelopmentEnv = maybe True (== "true") . lookupString "published" $ metadata isPublished
That way, as long as I preview the blog with HAKYLL_ENV=development stack exec site watch
, I can keep published: false
while working on a new post.
Please feel free to copy the code described above and use it for your Hakyll blog!