on master help sign in
Added simple pagination (unstable).
eaf0c23Jasper Van der Jeugt
hakyll.cabal+1
@@ -47,6 +47,7 @@ library
47 Text.Hakyll.Renderable
47 Text.Hakyll.Renderable
48 Text.Hakyll.Renderables
48 Text.Hakyll.Renderables
49 Text.Hakyll.Page
49 Text.Hakyll.Page
50+ Text.Hakyll.Paginate
50 Text.Hakyll.Util
51 Text.Hakyll.Util
51 Text.Hakyll.Tags
52 Text.Hakyll.Tags
52 Text.Hakyll.Internal.Cache
53 Text.Hakyll.Internal.Cache
src/Text/Hakyll/Context.hs+3−3
@@ -27,8 +27,8 @@ type ContextManipulation = Context -> Context
27-- | Do something with a value in a @Context@, but keep the old value as well.
27-- | Do something with a value in a @Context@, but keep the old value as well.
28-- This is probably the most common function to construct a
28-- This is probably the most common function to construct a
29-- @ContextManipulation@.
29-- @ContextManipulation@.
30−renderValue :: String -- ^ Key of which the value should be copied.
30+renderValue :: String -- ^ Key of which the value should be copied.
31− -> String -- ^ Key the value should be copied to.
31+ -> String -- ^ Key the value should be copied to.
32 -> (String -> String) -- ^ Function to apply on the value.
32 -> (String -> String) -- ^ Function to apply on the value.
33 -> ContextManipulation
33 -> ContextManipulation
34renderValue src dst f context = case M.lookup src context of
34renderValue src dst f context = case M.lookup src context of
@@ -41,7 +41,7 @@ renderValue src dst f context = case M.lookup src context of
41-- > changeValue "title" (map toUpper)
41-- > changeValue "title" (map toUpper)
42--
42--
43-- Will put the title in UPPERCASE.
43-- Will put the title in UPPERCASE.
44−changeValue :: String -- ^ Key of which the value should be changed.
44+changeValue :: String -- ^ Key to change.
45 -> (String -> String) -- ^ Function to apply on the value.
45 -> (String -> String) -- ^ Function to apply on the value.
46 -> ContextManipulation
46 -> ContextManipulation
47changeValue key = renderValue key key
47changeValue key = renderValue key key
src/Text/Hakyll/Paginate.hsnew file+74
@@ -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)
src/Text/Hakyll/Render.hs+8−8
@@ -26,9 +26,9 @@ import Text.Hakyll.Internal.CompressCss
26import Text.Hakyll.Internal.Render
26import Text.Hakyll.Internal.Render
27
27
28-- | Execute an IO action only when the cache is invalid.
28-- | Execute an IO action only when the cache is invalid.
29−depends :: FilePath -- ^ File to be rendered or created.
29+depends :: FilePath -- ^ File to be rendered or created.
30 -> [FilePath] -- ^ Files the render depends on.
30 -> [FilePath] -- ^ Files the render depends on.
31− -> Hakyll () -- ^ IO action to execute when the file is out of date.
31+ -> Hakyll () -- ^ Action to execute when the file is out of date.
32 -> Hakyll ()
32 -> Hakyll ()
33depends file dependencies action = do
33depends file dependencies action = do
34 destination <- toDestination file
34 destination <- toDestination file
@@ -37,8 +37,8 @@ depends file dependencies action = do
37
37
38-- | Render to a Page.
38-- | Render to a Page.
39render :: Renderable a
39render :: Renderable a
40− => FilePath -- ^ Template to use for rendering.
40+ => FilePath -- ^ Template to use for rendering.
41− -> a -- ^ Renderable object to render with given template.
41+ -> a -- ^ Renderable object to render with given template.
42 -> Hakyll Page -- ^ The body of the result will contain the render.
42 -> Hakyll Page -- ^ The body of the result will contain the render.
43render = renderWith id
43render = renderWith id
44
44
@@ -46,9 +46,9 @@ render = renderWith id
46-- first.
46-- first.
47renderWith :: Renderable a
47renderWith :: Renderable a
48 => ContextManipulation -- ^ Manipulation to apply on the context.
48 => ContextManipulation -- ^ Manipulation to apply on the context.
49− -> FilePath -- ^ Template to use for rendering.
49+ -> FilePath -- ^ Template to use for rendering.
50− -> a -- ^ Renderable object to render with given template.
50+ -> a -- ^ Data to render.
51− -> Hakyll Page -- ^ The body of the result will contain the render.
51+ -> Hakyll Page -- ^ Result of the render operation.
52renderWith manipulation templatePath renderable = do
52renderWith manipulation templatePath renderable = do
53 template <- readTemplate templatePath
53 template <- readTemplate templatePath
54 context <- toContext renderable
54 context <- toContext renderable
@@ -66,7 +66,7 @@ renderWith manipulation templatePath renderable = do
66--
66--
67renderAndConcat :: Renderable a
67renderAndConcat :: Renderable a
68 => [FilePath] -- ^ Templates to apply on every renderable.
68 => [FilePath] -- ^ Templates to apply on every renderable.
69− -> [a] -- ^ Renderables to render.
69+ -> [a] -- ^ Renderables to render.
70 -> Hakyll String
70 -> Hakyll String
71renderAndConcat = renderAndConcatWith id
71renderAndConcat = renderAndConcatWith id
72
72