如何在Hakyll html中为帖子的第二个目录提供第二个列表? [英] How to have a second list for a second directory of posts in Hakyll html?

查看:80
本文介绍了如何在Hakyll html中为帖子的第二个目录提供第二个列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在索引页面中有一个部分,列出了posts/*目录中的帖子.我想再有一个部分列出一个来自bibs/*目录的帖子.

I have a section in an index page that lists posts from the posts/* directory. What I would like is to have another section that lists posts from a bibs/* directory.

因此,它看起来像:

                    <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.hs templates/index.html .)谢谢您的时间,请让我知道是否可以澄清任何事情或提供其他信息.

The code I am using for my regular posts is below - how can I replicate the same list, but for a different directory? (I have cut the irrelevant code to save length, if you want to see the projects source, you can here, with the relevant files being site.hs and templates/index.html.) Thank you for your time, and please let me know if I can clarify anything or give additional information.

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

推荐答案

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

You can use the field and <> combinators to extend a Context (homeCtx in this case) with the contents of the lists under some tags. Here, I've renamed the tags body and body2 to posts and bibs because body is a tag with a special meaning in Hakyll. Remember to also rename the tags in 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

这篇关于如何在Hakyll html中为帖子的第二个目录提供第二个列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆