1

我在索引页面中有一个部分,列出了 posts/* 目录中的帖子。我想要的是另一个部分列出 bibs/* 目录中的帖子。

所以,它看起来像:

                    <section id="one" class="wrapper style2 spotlights">
                        <section>
                            <div class="content">
                                <div class="inner">
                                    <h2>Blog posts</h2>
                                    $body$
                                    <p><a href="./posts.html">See all.</a></p>
                                </div>
                            </div>
                        </section>
                    </section>
                    <!-- Two -->
                    <section id="two" class="wrapper style1 fade-up">
                        <div class="inner">
                            <h2>Bibliographies</h2>
                            $body2$
                            <p><a href="./bibs.html">See all bibs.</a></p>
                        </div>
                    </section>

目前,我收到错误

[ERROR] Hakyll.Web.Template.applyTemplate: Failed to apply template templates/index.html to item index.html:
    In expr '$body2$',
    Tried field title,
    Tried field date,
    Tried field body,
    No 'body2' field in metadata of item index.html,
    Tried field url,
    Tried field path,
    Tried field title,
    Missing field 'body2' in context

我用于常规帖子的代码如下 - 我如何复制相同的列表,但用于不同的目录?(为了节省篇幅,我剪掉了不相关的代码,如果你想看项目源码,你可以在这里,相关文件是site.hstemplates/index.html。)谢谢你的时间,请让我知道我是否可以澄清任何事情或提供更多信息。

defaultCtx :: Context String
defaultCtx = dateField "date" "%B %e, %Y" <> defaultContext

basicCtx :: String -> Context String
basicCtx title = constField "title" title <> defaultCtx

homeCtx :: Context String
homeCtx = basicCtx "Home"

allPostsCtx :: Context String
allPostsCtx = basicCtx "All posts"

feedCtx :: Context String
feedCtx = bodyField "description" <> defaultCtx

tagsCtx :: Tags -> Context String
tagsCtx tags = tagsField "prettytags" tags <> defaultCtx

postsCtx :: String -> String -> Context String
postsCtx title list = constField "body" list <> basicCtx title

externalizeUrls :: String -> Item String -> Compiler (Item String)
externalizeUrls root item = return $ withUrls ext <$> item
  where
    ext x = if isExternal x then x else root ++ x

unExternalizeUrls :: String -> Item String -> Compiler (Item String)
unExternalizeUrls root item = return $ withUrls unExt <$> item
  where
    unExt x = fromMaybe x $ stripPrefix root x

postList :: Tags -> Pattern -> ([Item String] -> Compiler [Item String]) -> Compiler String
postList tags pattern preprocess' = do
    postItemTpl <- loadBody "templates/postitem.html"
    posts <- preprocess' =<< loadAll pattern
    applyTemplateList postItemTpl (tagsCtx tags) posts

main :: IO ()
main = hakyllWith configuration $ do
    -- Build tags
    tags <- buildTags "posts/*" $ fromCapture "tags/*.html"
    let tagsCtx' = tagsCtx tags

    match "posts/*" $ do
        route   $ setExtension ".html"
        compile $ pandocCompiler
            >>= loadAndApplyTemplate "templates/post.html"     tagsCtx'
            >>= (externalizeUrls     $ feedRoot feedConfiguration)
            >>= saveSnapshot         "content"
            >>= (unExternalizeUrls   $ feedRoot feedConfiguration)
            >>= loadAndApplyTemplate "templates/default.html"  tagsCtx'
            >>= relativizeUrls

    create ["posts.html"] $ do
        route idRoute
        compile $ do
            list <- postList tags "posts/*" recentFirst
            makeItem list
                >>= loadAndApplyTemplate "templates/posts.html"   allPostsCtx
                >>= loadAndApplyTemplate "templates/default.html" allPostsCtx
                >>= relativizeUrls

    create ["index.html"] $ do
        route idRoute
        compile $ do
            list <- postList tags "posts/*" (fmap (take 10) . recentFirst)
            makeItem list
                >>= loadAndApplyTemplate "templates/index.html"   homeCtx
                >>= loadAndApplyTemplate "templates/default.html" homeCtx
                >>= relativizeUrls

    tagsRules tags $ \tag pattern -> do
        route idRoute
        compile $ do
            list <- postList tags pattern recentFirst

            let title       = "Posts tagged '" ++ tag ++ "'"
            let defaultCtx' = basicCtx title
            let postsCtx'   = postsCtx title list

            makeItem ""
                >>= loadAndApplyTemplate "templates/posts.html"   postsCtx'
                >>= loadAndApplyTemplate "templates/default.html" defaultCtx'
                >>= relativizeUrls
4

1 回答 1

1

您可以使用fieldand<>组合符来扩展Context(homeCtx在这种情况下) 与某些标签下的列表内容。在这里,我将标签bodybody2to重命名为postsbibs因为body是在 Hakyll 中具有特殊含义的标签。记住还要重命名templates/index.html.

    -- Index
    create ["index.html"] $ do
        route idRoute
        compile $ do
            let mkposts = postList tags "posts/*" (fmap (take 10) . recentFirst)
                mkbibs = bibList tags "bibs/*" (fmap (take 10) . recentFirst)
                homeCtx' = field "posts" (const mkposts)  -- Populate the context with those fields
                        <> field "bibs" (const mkbibs)    --
                        <> homeCtx
            makeItem ""  -- This doesn't matter since the next template does not contain "body" (after renaming it to "posts")
                >>= loadAndApplyTemplate "templates/index.html"   homeCtx'  -- This template mentions "posts" and "bibs", which will be looked up in homeCtx'
                >>= loadAndApplyTemplate "templates/default.html" homeCtx'
                >>= relativizeUrls
于 2020-08-13T15:57:00.417 回答