按自定义字段对 Hakyll 项目列表进行排序
Sort Hakyll item list by a custom field
我想在我的 post 中添加一个名为 coolness
的自定义字段,如下所示:
---
title: Something
coolness: 10
---
然后我想按酷度对我的 post 进行排序。我怎么做?我知道我可以按日期排序:
posts <- recentFirst =<< loadAll "posts/*"
使用 recentFirst
,但这是内置的,我真的不知道如何修改它以按 coolness
排序,因为它使用一些自定义方法来找出 post 的日期.
我们想用MonadMetadata
and getMetadataField
from Hakyll读取凉爽度,然后解析成一个数字,按照这个数字排序。
大量借鉴 The source for recentFirst
,你可以这样写:
{-# LANGUAGE TupleSections #-}
import Hakyll
import Control.Monad (void, (>>=), liftM)
import Data.Ord (comparing)
import Data.List(sortOn, sortBy)
import Data.Maybe(fromMaybe)
import Text.Read(readMaybe)
import Data.Foldable (toList)
-- this parses the coolness out of an item
-- it defaults to 0 if it's missing, or can't be parsed as an Int
coolness :: MonadMetadata m => Item a -> m Int
coolness i = do
mStr <- getMetadataField (itemIdentifier i) "coolness"
return $ (fromMaybe 0 $ mStr >>= readMaybe)
byCoolness :: MonadMetadata m => [Item a] -> m [Item a]
byCoolness = sortByM coolness
where
sortByM :: (Monad m, Ord k) => (a -> m k) -> [a] -> m [a]
sortByM f xs = liftM (map fst . sortBy (comparing snd)) $
mapM (\x -> liftM (x,) (f x)) xs
这根据提取的冷度值排序。
它按照越来越酷的方式排序,所以如果你想要“最酷的第一”,请执行:
posts <- reverse <$> (byCoolness =<< loadAll "posts/*")
我想在我的 post 中添加一个名为 coolness
的自定义字段,如下所示:
---
title: Something
coolness: 10
---
然后我想按酷度对我的 post 进行排序。我怎么做?我知道我可以按日期排序:
posts <- recentFirst =<< loadAll "posts/*"
使用 recentFirst
,但这是内置的,我真的不知道如何修改它以按 coolness
排序,因为它使用一些自定义方法来找出 post 的日期.
我们想用MonadMetadata
and getMetadataField
from Hakyll读取凉爽度,然后解析成一个数字,按照这个数字排序。
大量借鉴 The source for recentFirst
,你可以这样写:
{-# LANGUAGE TupleSections #-}
import Hakyll
import Control.Monad (void, (>>=), liftM)
import Data.Ord (comparing)
import Data.List(sortOn, sortBy)
import Data.Maybe(fromMaybe)
import Text.Read(readMaybe)
import Data.Foldable (toList)
-- this parses the coolness out of an item
-- it defaults to 0 if it's missing, or can't be parsed as an Int
coolness :: MonadMetadata m => Item a -> m Int
coolness i = do
mStr <- getMetadataField (itemIdentifier i) "coolness"
return $ (fromMaybe 0 $ mStr >>= readMaybe)
byCoolness :: MonadMetadata m => [Item a] -> m [Item a]
byCoolness = sortByM coolness
where
sortByM :: (Monad m, Ord k) => (a -> m k) -> [a] -> m [a]
sortByM f xs = liftM (map fst . sortBy (comparing snd)) $
mapM (\x -> liftM (x,) (f x)) xs
这根据提取的冷度值排序。 它按照越来越酷的方式排序,所以如果你想要“最酷的第一”,请执行:
posts <- reverse <$> (byCoolness =<< loadAll "posts/*")