Last week I was asked to review a draft of a blog post:
@RiccardoOdone I just found your blog and am really digging your Haskell content. I'm working on a blog explaining property based testing options, could I ask you to take a look at it? I'd love your feedback / opinion :)— Maxfield Chen (@_nihliphobe) May 13, 2020
That made me realize I don't have a way to do a similar trick. However, last week I worked on "Adding
published to Hakyll Posts". Thus, I already did the hard work on understanding the internals, so I could just sit back and code it.
Up until now the blog worked as follows:
- Published posts were compiled by Hakyll to
- Drafts were not compiled except when
HAKYLL_ENVwas set to
With the new changes:
- All posts are compiled by Hakyll.
- Published posts are compiled to
posts/*and appear in the archive.
- Drafts are compiled to
drafts/posts/*but do not appear in the archive.
In particular, only published posts are compiled to
- matchMetadata "posts/*" (isDevelopmentOrPublished env) $ do + matchMetadata "posts/*" isPublished $ do route $ setExtension "html"
Drafts are compiled to
drafts/posts/*. Also, when compiling the URL to the draft is printed:
matchMetadata "posts/*" (not . isPublished) $ do let draftPath = ("drafts/" <>) . (`replaceExtension` "html") . toFilePath route . customRoute $ draftPath let putDraftUrl path = traverse_ (unsafeCompiler . putStrLn) [ "----DRAFT----", (previewUrl <>) . draftPath . itemIdentifier $ path, "-------------" ] compile $ pandocCompiler >>= loadAndApplyTemplate "templates/post.html" postCtx >>= loadAndApplyTemplate "templates/default.html" postCtx >>= relativizeUrls >>= (\x -> putDraftUrl x >> pure x)
In the archive only published posts are included except when in development:
create ["archive.html"] $ do route idRoute compile $ do - posts <- recentFirst =<< loadAll "posts/*" + posts <- recentFirst =<< loadAllPublished env "posts/*"
loadAllPublished :: (Binary a, Typeable a) => [(String, String)] -> Pattern -> Compiler [Item a] loadAllPublished env pattern_ = if isDevelopmentEnv env then all else published where all = loadAll pattern_ published = publishedIds pattern_ >>= traverse load isDevelopmentEnv env = lookup "HAKYLL_ENV" env == Just "development"
A similar change appears in the Atom feed code:
- =<< loadAllSnapshots "posts/*" "content" + =<< loadAllSnapshotsPublished "posts/*" "content"
loadAllSnapshotsPublished :: (Binary a, Typeable a) => Pattern -> Snapshot -> Compiler [Item a] loadAllSnapshotsPublished pattern_ snapshot = publishedIds pattern_ >>= traverse (`loadSnapshot` snapshot) publishedIds :: MonadMetadata m => Pattern -> m [Identifier] publishedIds = fmap (fmap fst . filter (isPublished . snd)) . getAllMetadata
As always, feel free to go ahead and grab the code.
The draft I ended up reviewing was "Functional Fika — Nix and Haskell". Thanks Maxfield for the inspiration and for teaching me what fika is! ☕️