Hakyll says "Dependency cycle detected: ..."
Asked Answered
C

1

2

I'm trying to construct a site with 7 pages. Each page is defined using a .markdown input. On each page I want a header with links to all the other pages.

Now, this seems to be impossible since Hakyll tells me that I have a recursive dependency.

[ERROR] Hakyll.Core.Runtime.chase: Dependency cycle detected: posts/page1.markdown depends on posts/page1.markdown

I have identified the recursive dependency to this snippet.

match "posts/*" $ do
    route $ setExtension "html"
    compile $ do
        posts <- loadAll "posts/*"
        let indexCtx =
                listField "posts" postCtx (return posts) `mappend`
                constField "title" "Home"                `mappend`
                defaultContext

        pandocCompiler >>= loadAndApplyTemplate "templates/post.html" indexCtx
              >>= loadAndApplyTemplate "templates/default.html" indexCtx
              >>= relativizeUrls

I guess the problem is that I'm not allowed to match on the same template that a do a load on.

So how can I construct a context with a listField for all posts to be used when generating posts.

I guess an alternative would be to generate the links first, store them somehow and then include them in the posts. But how would I do that?

Covenanter answered 26/2, 2016 at 7:3 Comment(0)
P
3

By calling loadAll "posts/*" you load every fully compiled post before compile the current one, so it's a cycle dependency.

The most straightforward solution is to define another version of your posts:

match "posts/*" $ version "titleLine" $ do
  -- route
  -- compiler, maybe generate a link to real page here from file path

Then you can load them all without triggering a cycle dependency:

match "posts/*" $ do
  -- route
  compile $ do
    postList <- loadAll ("posts/*" .&&. hasVersion "titleLine")
    -- render the page

But you may have to manually generate the correct url from file path, after all a different version is a different page with different url. If you set the same routing for more than one page, the last one compiled will overwrite all the others.

It's OK in your case since the non-tagged version depends on the "titleLine" version so is compiled later, but generally it's dangerous to have same routing for different pages, without such a dependency version tagged page is always compiled later.

Penick answered 26/2, 2016 at 12:7 Comment(2)
Given that the "titleLine" version uses the same routing the url will be correct.Covenanter
I can confirm this worked for me; see also #47068351Tristatristam

© 2022 - 2024 — McMap. All rights reserved.