2

我已设置 Hakyll 以从博客文章中生成基本标签页面,如下所示:

main = do    
    hakyll $ do

        match "preambles/*.md" $ compile $ pandocCompiler >>= relativizeUrls

        tags <- buildTags "posts/*.md" (fromCapture "tags/*.html")

        tagsRules tags $ \tag pattern -> do
            let title = "Posts tagged \"" ++ tag ++ "\""
            route idRoute
            compile $ do
                posts <- recentFirst =<< loadAll pattern
                preamble <- loadBody $ fromFilePath ("preambles/" ++ tag ++ ".html")
                let ctx = constField "title" title
                        `mappend` listField "posts" postCtx (return posts)
                        `mappend` bodyField preamble
                        `mappend` defaultContext

                makeItem ""
                    >>= loadAndApplyTemplate "templates/tag.html" ctx
                    >>= loadAndApplyTemplate "templates/default.html" ctx
                    >>= relativizeUrls
...

我希望能够为每一页提供一个可选的序言。

为此,我希望在preambles目录中的每个标签都有一个降价文件,并在构建标签页面时尝试使用这些文件。但是,我不知道如何使它成为可选的,因为loadSnapshot如果fail没有找到。

这是一种合适的方法吗?如果是,我将如何处理丢失的数据?

另外,我不确定这bodyField是将数据传递给模板的适当方式。

4

1 回答 1

0

这对我来说似乎是一个完全合理的方法。

要回答您的主要问题,您可以利用Alternative实例Compiler来提供后备。

我也想提出一些小的改动。


首先,将您的序言规则替换为:

let preamblePattern = "preambles/*.md"
match preamblePattern $ do
    compile $ pandocCompiler 
                 >>= relativizeUrls
                 >>= saveSnapshot "preamble"
                 >>= pure . void

>>= pure . void将 转换Compiler (Item String)Compiler (Item ()). 这可以防止 Hakyll 为该规则生成任何输出文件。这saveSnapshot "preamble"意味着我们以后仍然可以获取内容。

除此之外,我已经将模式提取到一个变量中,原因稍后将变得清楚。


然后,替换:

preamble <- loadBody $ fromFilePath ("preambles/" ++ tag ++ ".html")

和:

let preambleIdent = fromCapture preamblePattern tag
preamble <- (loadSnapshotBody preambleIdent "preamble") <|> pure "fallback"

这使用fromCapture, 从 Pattern 生成标识符。这减少了重复,并且还回避了代码中的错误,".html"当.Identifier".md"

这使用loadSnapshotBody而不是loadBody因为上面建议的更改,我们从规则输出中删除内容。

最重要的是,它使用<|>fromAlternative来提供后备。您可能希望"fallback"用您想要的任何默认值替换。


最后,makeItem ""需要替换为makeItem preamble.

于 2020-10-11T22:05:12.883 回答