@@ -1,14 +1,10 @@
11module Text.Hakyll.Page
2− ( Page,
2+ ( Page (..),
33 PageValue,
44 addContext,
5− toURL,
6− getURL,
75 getBody,
86 readPage,
9− pageFromList,
10− concatPages,
11− concatPagesWith
7+ pageFromList
128 ) where
139
1410import qualified Data.Map as M
@@ -16,39 +12,41 @@ import qualified Data.List as L
1612import qualified Data.ByteString.Lazy.Char8 as B
1713import Data.Maybe
1814import Control.Monad
15+import Control.Arrow
1916
2017import System.FilePath
2118import System.IO
2219
2320import Text.Hakyll.Util
21+import Text.Hakyll.Renderable
2422import Text.Pandoc
2523
2624-- | A Page is basically key-value mapping. Certain keys have special
2725-- meanings, like for example url, body and title.
28−type Page = M.Map String PageValue
26+data Page = Page (M.Map String PageValue)
27+
28+getContext :: Page -> M.Map String PageValue
29+getContext (Page page) = page
2930
3031-- | We use a ByteString for obvious reasons.
3132type PageValue = B.ByteString
3233
3334-- | Add a key-value mapping to the Page.
3435addContext :: String -> String -> Page -> Page
35−addContext key value = M.insert key (B.pack value)
36−
37−-- | Get the url for a given page.
38−toURL :: FilePath -> FilePath
39−toURL = flip addExtension ".html" . dropExtension
36+addContext key value (Page page) = Page $ M.insert key (B.pack value) page
4037
4138-- | Get the URL for a certain page. This should always be defined. If
4239-- not, it will return trash.html.
43−getURL :: Page -> String
44−getURL context = let result = M.lookup "url" context
45− in case result of (Just url) -> B.unpack url
46− Nothing -> error "URL is not defined."
40+getPageURL :: Page -> String
41+getPageURL page =
42+ let result = M.lookup "url" $ getContext page
43+ in case result of (Just url) -> B.unpack url
44+ Nothing -> error "URL is not defined."
4745
4846-- | Get the body for a certain page. When not defined, the body will be
4947-- empty.
5048getBody :: Page -> PageValue
51−getBody context = fromMaybe B.empty $ M.lookup "body" context
49+getBody = fromMaybe B.empty . M.lookup "body" . getContext
5250
5351writerOptions :: WriterOptions
5452writerOptions = defaultWriterOptions
@@ -80,7 +78,7 @@ cachePage page = do
8078 makeDirectories destination
8179 handle <- openFile destination WriteMode
8280 hPutStrLn handle "---"
83− mapM_ (writePair handle) $ M.toList page
81+ mapM_ (writePair handle) $ M.toList $ getContext page
8482 hPutStrLn handle "---"
8583 B.hPut handle $ getBody page
8684 hClose handle
@@ -108,7 +106,7 @@ readPage pagePath = do
108106 -- Render file
109107 let rendered = B.pack $ (renderFunction $ takeExtension path) body
110108 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
112110
113111 -- Cache if needed
114112 if getFromCache then return () else cachePage page
@@ -118,16 +116,12 @@ readPage pagePath = do
118116
119117-- | Create a key-value mapping page from an association list.
120118pageFromList :: [(String, String)] -> Page
121−pageFromList = M.fromList . map packPair
119+pageFromList = Page . M.fromList . map packPair
122120 where packPair (k, v) = let pv = B.pack v
123121 in seq pv (k, pv)
124122
125−-- | Concat the bodies of pages, and return the result.
126−concatPages :: [Page] -> PageValue
127−concatPages = concatPagesWith "body"
128−
129−-- | Concat certain values of pages, and return the result.
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)
123+-- Make pages renderable
124+instance Renderable Page where
125+ getDependencies = (:[]) . flip addExtension ".html" . dropExtension . getPageURL
126+ getURL = getPageURL
127+ toContext = return . M.mapKeys B.pack . getContext