on master help sign in
Added simple caching.
commit08b2fe3eb44e1afc45e11cc76819ca62ba331baf authorJasper Van der Jeugt <jaspervdj@gmail.com> dateFri 4 Dec 2009, 18:32 (17 years ago) parentcf5aaee
3 files changed+47−9
src/Text/Hakyll/Page.hs+29−3 src/Text/Hakyll/Render.hs−4 src/Text/Hakyll/Util.hs+18−2
src/Text/Hakyll/Page.hs+29−3
@@ -14,6 +14,7 @@ import qualified Data.Map as M
1414import qualified Data.List as L
1515import qualified Data.ByteString.Lazy.Char8 as B
1616import Data.Maybe
17+import Control.Monad
1718
1819import System.FilePath
1920import System.IO
@@ -67,11 +68,30 @@ readMetaData handle = do
6768isDelimiter :: String -> Bool
6869isDelimiter = L.isPrefixOf "---"
6970
71+-- | Used for caching of files.
72+cachePage :: Page -> IO ()
73+cachePage page = do
74+ let destination = toCache $ getURL page
75+ makeDirectories destination
76+ handle <- openFile destination WriteMode
77+ hPutStrLn handle "---"
78+ mapM_ (writePair handle) $ M.toList page
79+ hPutStrLn handle "---"
80+ B.hPut handle $ getBody page
81+ hClose handle
82+ where writePair _ ("body", _) = return ()
83+ writePair h (k, v) = hPutStr h (k ++ ": ") >> B.hPut h v >> hPutStrLn h ""
84+
7085-- | Read a page from a file. Metadata is supported, and if the filename
7186-- has a .markdown extension, it will be rendered using pandoc. Note that
7287-- pages are not templates, so they should not contain $identifiers.
7388readPage :: FilePath -> IO Page
74−readPage path = do
89+readPage pagePath = do
90+ -- Check cache.
91+ getFromCache <- isCacheFileValid cacheFile pagePath
92+ let path = if getFromCache then cacheFile else pagePath
93+
94+ -- Read file.
7595 handle <- openFile path ReadMode
7696 line <- hGetLine handle
7797 (context, body) <- if isDelimiter line
@@ -80,10 +100,16 @@ readPage path = do
80100 return (md, c)
81101 else hGetContents handle >>= \b -> return ([], line ++ b)
82102
103+ -- Render file
83104 let rendered = B.pack $ (renderFunction $ takeExtension path) body
84− url = addExtension (dropExtension path) ".html"
85105 seq rendered $ hClose handle
86− return $ M.insert "body" rendered $ addContext "url" url $ pageFromList context
106+ let page = M.insert "body" rendered $ addContext "url" url $ pageFromList context
107+
108+ -- Cache if needed
109+ if getFromCache then return () else cachePage page
110+ return page
111+ where url = addExtension (dropExtension pagePath) ".html"
112+ cacheFile = toCache url
87113
88114-- | Create a key-value mapping page from an association list.
89115pageFromList :: [(String, String)] -> Page
src/Text/Hakyll/Render.hs−4
@@ -10,16 +10,12 @@ import qualified Data.ByteString.Lazy.Char8 as B
1010import qualified Data.Map as M
1111import Control.Monad
1212
13−import System.FilePath
1413import System.Directory
1514import System.IO
1615
1716import Text.Hakyll.Page
1817import Text.Hakyll.Util
1918
20−toDestination :: FilePath -> FilePath
21−toDestination path = "_site" </> path
22−
2319createContext :: Page -> Context
2420createContext = M.fromList . map packPair . M.toList
2521 where packPair (a, b) = (B.pack a, b)
src/Text/Hakyll/Util.hs+18−2
@@ -1,7 +1,10 @@
11module Text.Hakyll.Util
2− ( makeDirectories,
2+ ( toDestination,
3+ toCache,
4+ makeDirectories,
35 getRecursiveContents,
4− trim
6+ trim,
7+ isCacheFileValid
58 ) where
69
710import System.Directory
@@ -10,6 +13,12 @@ import Control.Monad
1013import Data.Char
1114import Data.List
1215
16+toDestination :: FilePath -> FilePath
17+toDestination path = "_site" </> path
18+
19+toCache :: FilePath -> FilePath
20+toCache path = "_cache" </> path
21+
1322-- | Given a path to a file, try to make the path writable by making
1423-- all directories on the path.
1524makeDirectories :: FilePath -> IO ()
@@ -44,3 +53,10 @@ split element = unfoldr splitOnce
4453 (x, xs) -> if null xs
4554 then Just (x, [])
4655 else Just (x, tail xs)
56+
57+-- | Check is a cache file is still valid.
58+isCacheFileValid :: FilePath -> FilePath -> IO Bool
59+isCacheFileValid cache file = doesFileExist cache >>= \exists ->
60+ if not exists then return False
61+ else liftM2 (<=) (getModificationTime file)
62+ (getModificationTime cache)