7

所以这有效:

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

在 archive.html 中创建最近帖子的列表;这是沼泽标准,它来自我认为的教程之一。除了 postCtx,它有点复杂,但在这里不应该相关。

但是,我想在普通帖子的侧边栏中列出一些最近的帖子。问题是最近的帖子最终取决于他们自己。我尝试将帖子本身从它自己生成的列表中排除,但我找不到这样做的好地方。这是我到目前为止所得到的:

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应该生成一个包含自身之外的所有最近的字段,但它似乎没有工作,或者它是错误的地方,因为:

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

到目前为止我被困住了。

编辑:

我看到Hakyll 说“检测到依赖循环:...”,这是 loadPosts 做的,所以我尝试了这个:

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

但这只是让我:

[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

,换句话说,我最终得到了两个最近的循环。

4

1 回答 1

1

编辑:事实证明我在这里描述的方法有一些缺点;有关问题的更新处理,请参见http://rlpowell.name/computing/general/hakyll_recent_posts.html


事实证明,https: //stackoverflow.com/a/35651294/1461430 上的技术对我有用,实际上它对我的效果比作者说的要好。这是我的代码的相关位:

match "posts/**" $ version "recents" $ do
    route $ (gsubRoute "posts/" (const "")) `composeRoutes` setExtension "html"
    compile $ do
        pandocCompilerWithTransform hblogPandocReaderOptions hblogPandocWriterOptions (titleFixer titles)
            >>= loadAndApplyTemplate "templates/post.html"    (postCtx allTags allCategories gitTimes)
            >>= relativizeUrls

match "posts/**" $ do
    route $ (gsubRoute "posts/" (const "")) `composeRoutes` setExtension "html"
    compile $ do
        myId <- getUnderlying
        recents <- (myRecentFirst gitTimes) =<< loadAll ("posts/**" .&&. hasVersion "recents")
        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

我不得不将 listField 和 recents 添加到其他几个使用 templates/default.html 的地方,但这很简单。

我还必须修改一个使用 Identifier 来查找从 git 中提取的时间列表的函数:

-- Pull a file's time out of the list
getGitTimeUTC :: Identifier -> [GitTimes] -> (GitTimes -> UTCTime) -> UTCTime
getGitTimeUTC ident times typeF =
  -- The identifier for the things compiled with the "recents"
  -- version has the identifierVersion "recents", but we don't care
  -- about that since the only reason that exists is to avoid loops,
  -- so we strip it here for our lookup.
  let fixedIdent = ident { identifierVersion = Nothing }
      timeList = filter (\x -> fixedIdent == (gtid x)) times in
    if length timeList /= 1 then
      -- It's not obvious to me how this could occur even in theory; I'd expect it to error out during getGitTimes
      error $ "getGitTimeUTC: Couldn't find the time for " ++ (show fixedIdent) ++ " in GitTimes list " ++ (show times)
    else
      typeF $ head timeList

结果,我没有文件重复,并且链接到最近的文件也没有问题;一切正常。

于 2017-11-02T16:24:05.480 回答