@@ -0,0 +1,74 @@
1+-- | Module aimed to paginate web pages.
2+module Text.Hakyll.Paginate
3+ ( PaginateConfiguration (..)
4+ , defaultPaginateConfiguration
5+ , paginate
6+ ) where
7+
8+import Text.Hakyll.Renderables
9+import Text.Hakyll.Renderable (Renderable, getUrl)
10+import Text.Hakyll.Util (link)
11+
12+-- | A configuration for a pagination.
13+data PaginateConfiguration = PaginateConfiguration
14+ { -- | Label for the link to the previous page.
15+ previousLabel :: String
16+ , -- | Label for the link to the next page.
17+ nextLabel :: String
18+ , -- | Label for the link to the first page.
19+ firstLabel :: String
20+ , -- | Label for the link to the last page.
21+ lastLabel :: String
22+ }
23+
24+-- | A simple default configuration for pagination.
25+defaultPaginateConfiguration :: PaginateConfiguration
26+defaultPaginateConfiguration = PaginateConfiguration
27+ { previousLabel = "Previous"
28+ , nextLabel = "Next"
29+ , firstLabel = "First"
30+ , lastLabel = "Last"
31+ }
32+
33+-- | The most important function for pagination. This function operates on a
34+-- list of renderables (the pages), and basically just adds fields to them
35+-- by combining them with a custom page.
36+--
37+-- The following metadata fields will be added:
38+--
39+-- - @$previous@: A link to the previous page.
40+-- - @$next@: A link to the next page.
41+-- - @$first@: A link to the first page.
42+-- - @$last@: A link to the last page.
43+-- - @$index@: 1-based index of the current page.
44+-- - @$length@: Total number of pages.
45+--
46+paginate :: (Renderable a)
47+ => PaginateConfiguration
48+ -> [a]
49+ -> [CombinedRenderable a CustomPage]
50+paginate configuration renderables = paginate' Nothing renderables (1 :: Int)
51+ where
52+ linkWithLabel f r = link (f configuration) `fmap` getUrl r
53+
54+ first = linkWithLabel firstLabel (head renderables)
55+ last' = linkWithLabel lastLabel (last renderables)
56+ length' = length renderables
57+
58+ paginate' _ [] _ = []
59+ paginate' maybePrev (x:xs) index =
60+ let previous = case maybePrev of
61+ (Just r) -> linkWithLabel previousLabel r
62+ Nothing -> return $ previousLabel configuration
63+ next = case xs of
64+ (n:_) -> linkWithLabel nextLabel n
65+ [] -> return $ nextLabel configuration
66+ customPage = createCustomPage "" []
67+ [ ("previous", Right previous)
68+ , ("next", Right next)
69+ , ("first", Right first)
70+ , ("last", Right last')
71+ , ("index", Left $ show index)
72+ , ("length", Left $ show length')
73+ ]
74+ in (x `combine` customPage) : paginate' (Just x) xs (index + 1)