summaryrefslogtreecommitdiff
path: root/src/Hakyll/Web/Page/List.hs
blob: 1edb2506389e82c37440e73a187d9fe00ef2f3c4 (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
-- | Provides an easy way to combine several pages in a list. The applications
-- are obvious:
--
-- * A post list on a blog
--
-- * An image list in a gallery
--
-- * A sitemap
--
module Hakyll.Web.Page.List
    ( setFieldPageList
    , pageListCompiler
    , chronological
    , recentFirst
    , sortByBaseName
    ) where

import Control.Arrow ((>>>), arr)
import Data.List (sortBy)
import Data.Monoid (Monoid, mconcat)
import Data.Ord (comparing)
import System.FilePath (takeBaseName)

import Hakyll.Core.Compiler
import Hakyll.Core.Identifier
import Hakyll.Core.Identifier.Pattern
import Hakyll.Web.Page
import Hakyll.Web.Page.Metadata
import Hakyll.Web.Template

-- | Set a field of a page to a listing of pages
--
setFieldPageList :: ([Page String] -> [Page String])  
                 -- ^ Determines list order
                 -> Identifier Template               
                 -- ^ Applied to every page
                 -> String
                 -- ^ Key indicating which field should be set
                 -> Pattern (Page String)             
                 -- ^ Selects pages to include in the list
                 -> Compiler (Page String) (Page String)
                 -- ^ Compiler that sets the page list in a field
setFieldPageList sort template key pattern =
    requireAllA pattern $ setFieldA key $ pageListCompiler sort template

-- | Create a list of pages
--
pageListCompiler :: ([Page String] -> [Page String])  -- ^ Determine list order
                 -> Identifier Template               -- ^ Applied to pages
                 -> Compiler [Page String] String     -- ^ Compiles page list
pageListCompiler sort template =
    arr sort >>> applyTemplateToList template >>> arr concatPages

-- | Apply a template to every page in a list
--
applyTemplateToList :: Identifier Template
                    -> Compiler [Page String] [Page String]
applyTemplateToList identifier =
    require identifier $ \posts template -> map (applyTemplate template) posts

-- | Concatenate the bodies of a page list
--
concatPages :: Monoid m => [Page m] -> m
concatPages = mconcat . map pageBody

-- | Sort pages chronologically. This function assumes that the pages have a
-- @year-month-day-title.extension@ naming scheme -- as is the convention in
-- Hakyll.
--
chronological :: [Page a] -> [Page a]
chronological = sortBy $ comparing $ takeBaseName . getField "path"

-- | The reverse of 'chronological'
--
recentFirst :: [Page a] -> [Page a]
recentFirst = reverse . chronological

-- | Deprecated, see 'chronological'
--
sortByBaseName :: [Page a] -> [Page a]
sortByBaseName = chronological
{-# DEPRECATED sortByBaseName "Use chronological" #-}