[awesome feature] Added combining of Renderables.
This commit is contained in:
parent
da31280dd7
commit
7af4014e3f
1 changed files with 52 additions and 8 deletions
|
@ -3,6 +3,9 @@ module Text.Hakyll.Renderables
|
|||
, createCustomPage
|
||||
, PagePath
|
||||
, createPagePath
|
||||
, CombinedRenderable
|
||||
, combine
|
||||
, combineWithURL
|
||||
) where
|
||||
|
||||
import qualified Data.Map as M
|
||||
|
@ -14,9 +17,9 @@ import Text.Hakyll.File
|
|||
|
||||
-- | A custom page.
|
||||
data CustomPage = CustomPage
|
||||
{ url :: String,
|
||||
dependencies :: [FilePath],
|
||||
mapping :: [(String, Either String (Hakyll String))]
|
||||
{ customPageURL :: String,
|
||||
customPageDependencies :: [FilePath],
|
||||
customPageContext :: [(String, Either String (Hakyll String))]
|
||||
}
|
||||
|
||||
-- | Create a custom page.
|
||||
|
@ -33,12 +36,12 @@ createCustomPage :: String -- ^ Destination of the page, relative to _site.
|
|||
createCustomPage = CustomPage
|
||||
|
||||
instance Renderable CustomPage where
|
||||
getDependencies = dependencies
|
||||
getURL = url
|
||||
getDependencies = customPageDependencies
|
||||
getURL = customPageURL
|
||||
toContext page = do
|
||||
values <- mapM (either (return) (>>= return) . snd) (mapping page)
|
||||
return $ M.fromList $ [ ("url", url page)
|
||||
] ++ zip (map fst $ mapping page) values
|
||||
values <- mapM (either return id . snd) (customPageContext page)
|
||||
return $ M.fromList $ [ ("url", customPageURL page)
|
||||
] ++ zip (map fst $ customPageContext page) values
|
||||
|
||||
-- | PagePath is a class that wraps a FilePath. This is used to render Pages
|
||||
-- without reading them first through use of caching.
|
||||
|
@ -53,3 +56,44 @@ instance Renderable PagePath where
|
|||
getDependencies (PagePath path) = return path
|
||||
getURL (PagePath path) = toURL path
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue