summaryrefslogtreecommitdiff
path: root/lib/Hakyll/Web/Template/List.hs
blob: 458c4a7664dd8000f26b4111f326521465065471 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
--------------------------------------------------------------------------------
-- | Provides an easy way to combine several items in a list. The applications
-- are obvious:
--
-- * A post list on a blog
--
-- * An image list in a gallery
--
-- * A sitemap
{-# LANGUAGE TupleSections #-}
module Hakyll.Web.Template.List
    ( applyTemplateList
    , applyJoinTemplateList
    , chronological
    , recentFirst
    , sortChronological
    , sortRecentFirst
    ) where


--------------------------------------------------------------------------------
import           Control.Monad               (liftM)
import           Control.Monad.Fail          (MonadFail)
import           Data.List                   (intersperse, sortBy)
import           Data.Ord                    (comparing)
import           Data.Time.Locale.Compat     (defaultTimeLocale)


--------------------------------------------------------------------------------
import           Hakyll.Core.Compiler
import           Hakyll.Core.Identifier
import           Hakyll.Core.Item
import           Hakyll.Core.Metadata
import           Hakyll.Web.Template
import           Hakyll.Web.Template.Context


--------------------------------------------------------------------------------
-- | Generate a string of a listing of pages, after applying a template to each
-- page.
applyTemplateList :: Template
                  -> Context a
                  -> [Item a]
                  -> Compiler String
applyTemplateList = applyJoinTemplateList ""


--------------------------------------------------------------------------------
-- | Join a listing of pages with a string in between, after applying a template
-- to each page.
applyJoinTemplateList :: String
                      -> Template
                      -> Context a
                      -> [Item a]
                      -> Compiler String
applyJoinTemplateList delimiter tpl context items = do
    items' <- mapM (applyTemplate tpl context) items
    return $ concat $ intersperse delimiter $ map itemBody items'


--------------------------------------------------------------------------------
-- | Sort pages chronologically. Uses the same method as 'dateField' for
-- extracting the date.
chronological :: (MonadMetadata m, MonadFail m) => [Item a] -> m [Item a]
chronological =
    sortByM $ getItemUTC defaultTimeLocale . itemIdentifier
  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


--------------------------------------------------------------------------------
-- | The reverse of 'chronological'
recentFirst :: (MonadMetadata m, MonadFail m) => [Item a] -> m [Item a]
recentFirst = liftM reverse . chronological


--------------------------------------------------------------------------------
-- | Version of 'chronological' which doesn't need the actual items.
sortChronological
    :: (MonadMetadata m, MonadFail m) => [Identifier] -> m [Identifier]
sortChronological ids =
    liftM (map itemIdentifier) $ chronological [Item i () | i <- ids]


--------------------------------------------------------------------------------
-- | Version of 'recentFirst' which doesn't need the actual items.
sortRecentFirst
    :: (MonadMetadata m, MonadFail m) => [Identifier] -> m [Identifier]
sortRecentFirst ids =
    liftM (map itemIdentifier) $ recentFirst [Item i () | i <- ids]