我正在尝试为Hakyll中的帖子生成HTML,这些帖子的元数据中有versions
条目。例如,帖子可能有versions: Python 3.4, pytest 1.5.2
,该在帖子底部的格式很好。
为此,我想创建一个加载元数据并创建一个ListField
的上下文。类似于以下存根的内容:
versionsCtx :: Context String
versionsCtx = listFieldWith "versions" ctx (item -> do
versions <- getMetadataField (itemIdentifier item) "versions"
return $ case versions of
Just lst -> map (mkVersinoItem . trim) $ splitAll "," lst
Nothing -> [])
where ctx = field "version" (return . itemBody)
mkVersionItem version = Item {
itemIdentifier = fromString ("version/" ++ version),
itemBody = version
}
在我的post.html
模板中,我有:
...
<section>
$body$
$if(versions)$
<hr />
<ul>
$for(versions)$
<li>$version$</li>
$endfor$
</ul>
$else$
<p>Fail...</p>
$endif$
</section>
...
然而,我尝试了许多不同的versionsCtx
定义,并在网上找到了类似的尝试。似乎都不起作用,帖子总是以"失败..."呈现。我做错了什么?
编辑:更新了带有建议和澄清的问题。
您的代码存在多个问题:
getMetadataField
提供了一个Maybe
类型,在Haskell中,它有数据构造函数Just
和Nothing
,而不是Some
和None
。makeItem
函数创建一个已经包装在Compiler
中的Item
,导致以下错误:
• Couldn't match type ‘Compiler (Item String)’ with ‘Item String’
Expected type: Compiler [Item String]
Actual type: Compiler [Compiler (Item String)]
虽然您可以尝试从中提取项目,但使用如下所示的内容从头开始创建项目可能更干净:
mkVersionItem version = Item {
itemIdentifier = fromString ("version/" ++ version),
itemBody = version
}
- 我没有看到您将新创建的上下文添加到帖子上下文中。你做到了吗?
- 如文档中所述,附加
Context
的顺序很重要。从您的问题中看不出来,但您可能正在使用defaultContext
,其中包括metadataField
.您在帖子的元数据块中versions
字段,因此当defaultContext
获胜时,它将versions
作为模板中的字符串字段提供。$if(versions)$
由于某种原因跳转到else
分支,当versions
是字符串字段时,这就解释了为什么显示"Fail"。当您将for
循环移到条件块之外时,您可以在控制台中看到一个信息量更大的错误:
[ERROR] Hakyll.Web.Template.applyTemplateWith: expected ListField but got StringField for expr versions
完整的代码可能如下所示:
import Data.String (fromString)
postCtx :: Context String
postCtx =
versionsCtx `mappend`
dateField "date" "%B %e, %Y" `mappend`
defaultContext
versionsCtx :: Context String
versionsCtx = listFieldWith "versions" ctx (item -> do
versions <- getMetadataField (itemIdentifier item) "versions"
return $ case versions of
Just lst -> map (mkVersionItem . trim) $ splitAll "," lst
Nothing -> []
)
where
ctx = field "version" (return . itemBody)
mkVersionItem version = Item {
itemIdentifier = fromString ("version/" ++ version),
itemBody = version
}