So this works:
create ["archive.html"] $ do
route idRoute
compile $ do
posts <- (myRecentFirst gitTimes) =<< loadAll "posts/**"
let archiveCtx =
listField "posts" (postCtx allTags allCategories gitTimes) (return posts) `mappend`
constField "title" "Archives" `mappend`
(postCtx allTags allCategories gitTimes)
makeItem ""
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
>>= relativizeUrls
to create a list of recent posts in archive.html ; this is bog-standard, it came from one of the tutorials I think. Except for postsCtx, which is a tad complicated, but shouldn't be relevant here.
However, I want to put a list of a few recent posts in the sidebar of normal posts. The problem becomes that the recent posts end up depending on themselves. I tried excluding the post itself from its own generated list, but I couldn't find a good place to do that. Here's what I've got so far:
match "posts/**" $ do
route $ (gsubRoute "posts/" (const "")) `composeRoutes` setExtension "html"
compile $ do
recents <- (myRecentFirst gitTimes) =<< loadAll "posts/**"
let postsContext = postCtx allTags allCategories gitTimes `mappend`
-- Show recent posts
recentsNotSelfField "recents" (postCtx allTags allCategories gitTimes) (return $ take 3 recents)
pandocCompilerWithTransform hblogPandocReaderOptions hblogPandocWriterOptions (titleFixer titles)
>>= loadAndApplyTemplate "templates/post.html" postsContext
>>= loadAndApplyTemplate "templates/default.html" postsContext
>>= relativizeUrls
recentsNotSelfField :: String -> Context a -> Compiler [Item a] -> Context b
recentsNotSelfField key context items = Context $ \k _ i ->
if k == key then do
let myId = itemIdentifier i
strippedItems <- items
let remains = filter (\x -> (itemIdentifier x) /= myId) strippedItems
return $ ListField context remains
else
CA.empty
recentsNotSelfField should produce a field with all the recents except itself, but it doesn't seem to be working or it's the wrong place to do that, because:
Initialising...
Creating store...
Creating provider...
Running rules...
Checking for out-of-date items
Compiling
[ERROR] Hakyll.Core.Runtime.chase: Dependency cycle detected: posts/computing/contact.md depends on posts/computing/contact.md
I'm stuck so far.
EDIT:
I saw Hakyll says "Dependency cycle detected: ..." , that it's the loadPosts that does it, so I tried this:
match "posts/**" $ do
route $ (gsubRoute "posts/" (const "")) `composeRoutes` setExtension "html"
compile $ do
myId <- getUnderlying
recents <- (myRecentFirst gitTimes) =<< loadAll ("posts/**" .&&. complement (fromList [myId]))
let postsContext = postCtx allTags allCategories gitTimes `mappend`
-- Show recent posts
listField "recents" (postCtx allTags allCategories gitTimes) (return $ take 3 recents)
pandocCompilerWithTransform hblogPandocReaderOptions hblogPandocWriterOptions (titleFixer titles)
>>= loadAndApplyTemplate "templates/post.html" postsContext
>>= loadAndApplyTemplate "templates/default.html" postsContext
>>= relativizeUrls
but that just gets me:
[ERROR] Hakyll.Core.Runtime.chase: Dependency cycle detected: posts/computing/contact.md depends on posts/computing/general/ched.md depends on posts/computing/contact.md
, in other words I end up with the two most recent cycling around each other.
posts <- getMatches "posts/*"
and thenmetadatas <- mapM getMetadata posts
but it is incomplete; if someone knows how to turn metadatas into a context that contains the title and url, they can write a good clean answer to this question. – Skyway