@@ -1,14 +1,10 @@
1module Text.Hakyll.Page
1module Text.Hakyll.Page
2− ( Page,
2+ ( Page (..),
4 addContext,
4 addContext,
9− pageFromList,
7+ pageFromList
14import qualified Data.Map as M
10import qualified Data.Map as M
@@ -16,39 +12,41 @@ import qualified Data.List as L
16import qualified Data.ByteString.Lazy.Char8 as B
12import qualified Data.ByteString.Lazy.Char8 as B
17import Data.Maybe
13import Data.Maybe
18import Control.Monad
14import Control.Monad
20import System.FilePath
17import System.FilePath
21import System.IO
18import System.IO
23import Text.Hakyll.Util
20import Text.Hakyll.Util
21+import Text.Hakyll.Renderable
24import Text.Pandoc
22import Text.Pandoc
26-- | A Page is basically key-value mapping. Certain keys have special
24-- | A Page is basically key-value mapping. Certain keys have special
27-- meanings, like for example url, body and title.
25-- meanings, like for example url, body and title.
28−type Page = M.Map String PageValue
26+data Page = Page (M.Map String PageValue)
28+getContext :: Page -> M.Map String PageValue
29+getContext (Page page) = page
30-- | We use a ByteString for obvious reasons.
31-- | We use a ByteString for obvious reasons.
31type PageValue = B.ByteString
32type PageValue = B.ByteString
33-- | Add a key-value mapping to the Page.
34-- | Add a key-value mapping to the Page.
34addContext :: String -> String -> Page -> Page
35addContext :: String -> String -> Page -> Page
35−addContext key value = M.insert key (B.pack value)
36+addContext key value (Page page) = Page $ M.insert key (B.pack value) page
37−-- | Get the url for a given page.
38−toURL :: FilePath -> FilePath
39−toURL = flip addExtension ".html" . dropExtension
41-- | Get the URL for a certain page. This should always be defined. If
38-- | Get the URL for a certain page. This should always be defined. If
42-- not, it will return trash.html.
39-- not, it will return trash.html.
43−getURL :: Page -> String
40+getPageURL :: Page -> String
44−getURL context = let result = M.lookup "url" context
42+ let result = M.lookup "url" $ getContext page
45− in case result of (Just url) -> B.unpack url
43+ in case result of (Just url) -> B.unpack url
46− Nothing -> error "URL is not defined."
44+ Nothing -> error "URL is not defined."
48-- | Get the body for a certain page. When not defined, the body will be
46-- | Get the body for a certain page. When not defined, the body will be
50getBody :: Page -> PageValue
48getBody :: Page -> PageValue
51−getBody context = fromMaybe B.empty $ M.lookup "body" context
49+getBody = fromMaybe B.empty . M.lookup "body" . getContext
53writerOptions :: WriterOptions
51writerOptions :: WriterOptions
54writerOptions = defaultWriterOptions
52writerOptions = defaultWriterOptions
@@ -80,7 +78,7 @@ cachePage page = do
80 makeDirectories destination
78 makeDirectories destination
81 handle <- openFile destination WriteMode
79 handle <- openFile destination WriteMode
82 hPutStrLn handle "---"
80 hPutStrLn handle "---"
83− mapM_ (writePair handle) $ M.toList page
81+ mapM_ (writePair handle) $ M.toList $ getContext page
84 hPutStrLn handle "---"
82 hPutStrLn handle "---"
85 B.hPut handle $ getBody page
83 B.hPut handle $ getBody page
86 hClose handle
84 hClose handle
@@ -108,7 +106,7 @@ readPage pagePath = do
108 -- Render file
106 -- Render file
109 let rendered = B.pack $ (renderFunction $ takeExtension path) body
107 let rendered = B.pack $ (renderFunction $ takeExtension path) body
110 seq rendered $ hClose handle
108 seq rendered $ hClose handle
111− let page = M.insert "body" rendered $ addContext "url" url $ pageFromList context
109+ let page = addContext "url" url $ Page $ M.fromList $ ("body", rendered) : map (second B.pack) context
113 -- Cache if needed
111 -- Cache if needed
114 if getFromCache then return () else cachePage page
112 if getFromCache then return () else cachePage page
@@ -118,16 +116,12 @@ readPage pagePath = do
119-- | Create a key-value mapping page from an association list.
117-- | Create a key-value mapping page from an association list.
120pageFromList :: [(String, String)] -> Page
118pageFromList :: [(String, String)] -> Page
121−pageFromList = M.fromList . map packPair
119+pageFromList = Page . M.fromList . map packPair
122 where packPair (k, v) = let pv = B.pack v
120 where packPair (k, v) = let pv = B.pack v
123 in seq pv (k, pv)
121 in seq pv (k, pv)
125−-- | Concat the bodies of pages, and return the result.
123+-- Make pages renderable
126−concatPages :: [Page] -> PageValue
124+instance Renderable Page where
127−concatPages = concatPagesWith "body"
125+ getDependencies = (:[]) . flip addExtension ".html" . dropExtension . getPageURL
128−
126+ getURL = getPageURL
129−-- | Concat certain values of pages, and return the result.
127+ toContext = return . M.mapKeys B.pack . getContext
130−concatPagesWith :: String -- ^ Key of which to concat the values.
131− -> [Page] -- ^ Pages to get the values from.
132− -> PageValue -- ^ The concatenation.
133−concatPagesWith key = B.concat . map (fromMaybe B.empty . M.lookup key)