Hakyll で Route を変更して markdown を pandoc compiler を通してもリンク先は自動で更新されない。
このため、markdown 内の link を手動で書き替えてやる必要がある
Hakyll で定義されている withUrls
を使用するとString->String
の変換を
各種 URL に適用することができる。これを使用して変更したい URL のみ上書きする。
実装を用いて説明する。
parseInnerLinks
:parseInnerLink
をwithUrls
ですべての URL に対して適用するparseInnerLink
:/posts
の接頭辞の url のみparsePostLink
を適用する
parseInnerLinks :: Item String -> Compiler (Item String)
= pure . fmap (withUrls parseInnerLink)
parseInnerLinks
parseInnerLink :: String -> String
parseInnerLink url| isExternal url = url
| "/posts" `L.isPrefixOf` url =
parsePostLink url| otherwise =
url
parsePostLink
:#
を含んでいる(特定のセクションへのリンク)を考慮した処理。#
以前の URL を変換し#
以後を再結合するconvPostUrl
:Route
の変更に使用したString->String
の変換を再利用する。Identifier
を取得する際、先頭の/
が邪魔になるためtail
で除去している。
parsePostLink :: String -> String
= case map T.unpack . T.splitOn "#" $ T.pack url of
parsePostLink url -> addHtml . convPostUrl $ base
[base] -> (++ section) . (++ "#") . addHtml . convPostUrl $ base
[base, section]
convPostUrl :: String -> String
= (++) "/" . getLangPath . fromFilePath $ tail url
convPostUrl url
addHtml :: String -> String
= (++ ".html") addHtml
定義したparseInnerLinks
は次にように使用することができる。
pandocCompiler>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= parseInnerLinks
>>= relativizeUrls