[awesome feature] Added combining of Renderables.

This commit is contained in:
Jasper Van der Jeugt 2010-01-19 09:53:52 +01:00
parent da31280dd7
commit 7af4014e3f

View file

@ -3,6 +3,9 @@ module Text.Hakyll.Renderables
, createCustomPage , createCustomPage
, PagePath , PagePath
, createPagePath , createPagePath
, CombinedRenderable
, combine
, combineWithURL
) where ) where
import qualified Data.Map as M import qualified Data.Map as M
@ -14,9 +17,9 @@ import Text.Hakyll.File
-- | A custom page. -- | A custom page.
data CustomPage = CustomPage data CustomPage = CustomPage
{ url :: String, { customPageURL :: String,
dependencies :: [FilePath], customPageDependencies :: [FilePath],
mapping :: [(String, Either String (Hakyll String))] customPageContext :: [(String, Either String (Hakyll String))]
} }
-- | Create a custom page. -- | Create a custom page.
@ -33,12 +36,12 @@ createCustomPage :: String -- ^ Destination of the page, relative to _site.
createCustomPage = CustomPage createCustomPage = CustomPage
instance Renderable CustomPage where instance Renderable CustomPage where
getDependencies = dependencies getDependencies = customPageDependencies
getURL = url getURL = customPageURL
toContext page = do toContext page = do
values <- mapM (either (return) (>>= return) . snd) (mapping page) values <- mapM (either return id . snd) (customPageContext page)
return $ M.fromList $ [ ("url", url page) return $ M.fromList $ [ ("url", customPageURL page)
] ++ zip (map fst $ mapping page) values ] ++ zip (map fst $ customPageContext page) values
-- | PagePath is a class that wraps a FilePath. This is used to render Pages -- | PagePath is a class that wraps a FilePath. This is used to render Pages
-- without reading them first through use of caching. -- without reading them first through use of caching.
@ -53,3 +56,44 @@ instance Renderable PagePath where
getDependencies (PagePath path) = return path getDependencies (PagePath path) = return path
getURL (PagePath path) = toURL path getURL (PagePath path) = toURL path
toContext (PagePath path) = readPage path >>= toContext toContext (PagePath path) = readPage path >>= toContext
-- | A combination of two other renderables.
data CombinedRenderable a b = CombinedRenderable a b
| CombinedRenderableWithURL FilePath a b
-- | Combine two renderables. The url will always be taken from the first
-- "Renderable". Also, if a `$key` is present in both renderables, the
-- value from the first "Renderable" will be taken as well.
combine :: (Renderable a, Renderable b) => a -> b -> CombinedRenderable a b
combine = CombinedRenderable
-- | Combine two renderables and set a custom URL.
combineWithURL :: (Renderable a, Renderable b)
=> FilePath
-> a
-> b
-> CombinedRenderable a b
combineWithURL = CombinedRenderableWithURL
-- | Render combinations.
instance (Renderable a, Renderable b)
=> Renderable (CombinedRenderable a b) where
-- Add the dependencies.
getDependencies (CombinedRenderable a b) =
getDependencies a ++ getDependencies b
getDependencies (CombinedRenderableWithURL _ a b) =
getDependencies a ++ getDependencies b
-- Take the url from the first renderable, or the specified URL.
getURL (CombinedRenderable a _) = getURL a
getURL (CombinedRenderableWithURL url _ _) = url
-- Take a union of the contexts.
toContext (CombinedRenderable a b) = do
c1 <- toContext a
c2 <- toContext b
return $ c1 `M.union` c2
toContext (CombinedRenderableWithURL url a b) = do
c <- toContext (CombinedRenderable a b)
return $ (M.singleton "url" url) `M.union` c