on master help sign in
Hamlet support (experimental)
commit69ca4255f07b147082614af34a883b557f456a74 authorJasper Van der Jeugt <jaspervdj@gmail.com> dateThu 5 Aug 2010, 18:41 (16 years ago) parent2c8d76c
6 files changed+97−28
hakyll.cabal+5−2 src/Text/Hakyll.hs+2 src/Text/Hakyll/HakyllMonad.hs+3 src/Text/Hakyll/Internal/Template.hs+12−26 src/Text/Hakyll/Internal/Template/Hamlet.hs+44 src/Text/Hakyll/Internal/Template/Template.hs+31
hakyll.cabal+5−2
@@ -38,8 +38,9 @@ library
3838 mtl == 1.*,
3939 old-locale == 1.*,
4040 old-time == 1.*,
41− time == 1.*,
42− binary >= 0.5
41+ time >= 1.2,
42+ binary >= 0.5,
43+ hamlet == 0.4.2
4344 exposed-modules: Network.Hakyll.SimpleServer
4445 Text.Hakyll
4546 Text.Hakyll.Context
@@ -61,3 +62,5 @@ library
6162 Text.Hakyll.Internal.FileType
6263 Text.Hakyll.Internal.Page
6364 Text.Hakyll.Internal.Template
65+ Text.Hakyll.Internal.Template.Template
66+ Text.Hakyll.Internal.Template.Hamlet
src/Text/Hakyll.hs+2
@@ -23,6 +23,7 @@ import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
2323import System.Time (getClockTime)
2424
2525import Text.Pandoc
26+import Text.Hamlet (defaultHamletSettings)
2627
2728import Network.Hakyll.SimpleServer (simpleServer)
2829import Text.Hakyll.HakyllMonad
@@ -59,6 +60,7 @@ defaultHakyllConfiguration absoluteUrl' = HakyllConfiguration
5960 , previewMode = BuildOnRequest
6061 , pandocParserState = defaultPandocParserState
6162 , pandocWriterOptions = defaultPandocWriterOptions
63+ , hamletSettings = defaultHamletSettings
6264 }
6365
6466-- | Main function to run Hakyll with the default configuration. The
src/Text/Hakyll/HakyllMonad.hs+3
@@ -15,6 +15,7 @@ import qualified Data.Map as M
1515import System.IO (hPutStrLn, stderr)
1616
1717import Text.Pandoc (ParserState, WriterOptions)
18+import Text.Hamlet (HamletSettings)
1819
1920import Text.Hakyll.Context (Context (..))
2021
@@ -48,6 +49,8 @@ data HakyllConfiguration = HakyllConfiguration
4849 pandocParserState :: ParserState
4950 , -- | Pandoc writer options
5051 pandocWriterOptions :: WriterOptions
52+ , -- | Hamlet settings (if you use hamlet for templates)
53+ hamletSettings :: HamletSettings
5154 }
5255
5356-- | Simplified @ask@ function for the Hakyll monad stack.
src/Text/Hakyll/Internal/Template.hs+12−26
@@ -10,8 +10,6 @@ module Text.Hakyll.Internal.Template
1010import Control.Applicative ((<$>))
1111import Data.List (isPrefixOf)
1212import Data.Char (isAlphaNum)
13−import Data.Binary
14−import Control.Monad (liftM, liftM2)
1513import Data.Maybe (fromMaybe)
1614import System.FilePath ((</>))
1715import qualified Data.Map as M
@@ -20,13 +18,8 @@ import Text.Hakyll.Context (Context (..))
2018import Text.Hakyll.HakyllMonad (Hakyll)
2119import Text.Hakyll.Internal.Cache
2220import Text.Hakyll.Internal.Page
23−
24−-- | Datatype used for template substitutions.
25−data Template = Chunk String Template
26− | Identifier String Template
27− | EscapeCharacter Template
28− | End
29− deriving (Show, Read, Eq)
21+import Text.Hakyll.Internal.Template.Template
22+import Text.Hakyll.Internal.Template.Hamlet
3023
3124-- | Construct a @Template@ from a string.
3225fromString :: String -> Template
@@ -48,14 +41,20 @@ readTemplate path = do
4841 if isCacheMoreRecent'
4942 then getFromCache fileName
5043 else do
51− page <- unContext <$> readPage path
52− let body = fromMaybe (error $ "No body in template " ++ fileName)
53− (M.lookup "body" page)
54− template = fromString body
44+ template <- if isHamletRTFile path
45+ then readHamletTemplate
46+ else readDefaultTemplate
5547 storeInCache template fileName
5648 return template
5749 where
5850 fileName = "templates" </> path
51+ readDefaultTemplate = do
52+ page <- unContext <$> readPage path
53+ let body = fromMaybe (error $ "No body in template " ++ fileName)
54+ (M.lookup "body" page)
55+ return $ fromString body
56+
57+ readHamletTemplate = fromHamletRT <$> readHamletRT path
5958
6059-- | Substitutes @$identifiers@ in the given @Template@ by values from the given
6160-- "Context". When a key is not found, it is left as it is. You can specify
@@ -80,16 +79,3 @@ regularSubstitute = substitute "$$"
8079-- escaped characters.
8180finalSubstitute :: Template -> Context -> String
8281finalSubstitute = substitute "$"
83−
84−instance Binary Template where
85− put (Chunk string template) = put (0 :: Word8) >> put string >> put template
86− put (Identifier key template) = put (1 :: Word8) >> put key >> put template
87− put (EscapeCharacter template) = put (2 :: Word8) >> put template
88− put (End) = put (3 :: Word8)
89−
90− get = do tag <- getWord8
91− case tag of 0 -> liftM2 Chunk get get
92− 1 -> liftM2 Identifier get get
93− 2 -> liftM EscapeCharacter get
94− 3 -> return End
95− _ -> error "Error reading template"
src/Text/Hakyll/Internal/Template/Hamlet.hsnew file+44
@@ -0,0 +1,44 @@
1+-- | Support for Hamlet templates in Hakyll.
2+--
3+module Text.Hakyll.Internal.Template.Hamlet
4+ ( isHamletRTFile
5+ , readHamletRT
6+ , fromHamletRT
7+ ) where
8+
9+import Data.List (intercalate)
10+import Control.Monad.Trans (liftIO)
11+import System.FilePath (takeExtension)
12+
13+import Text.Hamlet.RT
14+
15+import Text.Hakyll.Internal.Template.Template
16+import Text.Hakyll.HakyllMonad (Hakyll, askHakyll, hamletSettings)
17+
18+-- | Determine if a file is a hamlet template by extension.
19+--
20+isHamletRTFile :: FilePath -> Bool
21+isHamletRTFile fileName = takeExtension fileName `elem` [".hamlet", ".hml"]
22+
23+-- | Read a 'HamletRT' by file name.
24+--
25+readHamletRT :: FilePath -- ^ Filename of the template
26+ -> Hakyll HamletRT -- ^ Resulting hamlet template
27+readHamletRT fileName = do
28+ settings <- askHakyll hamletSettings
29+ string <- liftIO $ readFile fileName
30+ liftIO $ parseHamletRT settings string
31+
32+
33+-- | Convert a 'HamletRT' to a 'Template'
34+--
35+fromHamletRT :: HamletRT -- ^ Hamlet runtime template
36+ -> Template -- ^ Hakyll template
37+fromHamletRT (HamletRT sd) = fromSimpleDoc sd
38+ where
39+ fromSimpleDoc :: [SimpleDoc] -> Template
40+ fromSimpleDoc [] = End
41+ fromSimpleDoc (SDRaw chunk : xs) = Chunk chunk $ fromSimpleDoc xs
42+ fromSimpleDoc (SDVar vars : xs) =
43+ Identifier (intercalate "." vars) $ fromSimpleDoc xs
44+ fromSimpleDoc (_ : xs) = fromSimpleDoc xs -- Unsupported elements
src/Text/Hakyll/Internal/Template/Template.hsnew file+31
@@ -0,0 +1,31 @@
1+-- | Module containing the template data structure.
2+--
3+module Text.Hakyll.Internal.Template.Template
4+ ( Template (..)
5+ ) where
6+
7+import Control.Monad (liftM, liftM2)
8+import Data.Word (Word8)
9+
10+import Data.Binary (Binary, get, put, getWord8)
11+
12+-- | Datatype used for template substitutions.
13+--
14+data Template = Chunk String Template
15+ | Identifier String Template
16+ | EscapeCharacter Template
17+ | End
18+ deriving (Show, Read, Eq)
19+
20+instance Binary Template where
21+ put (Chunk string template) = put (0 :: Word8) >> put string >> put template
22+ put (Identifier key template) = put (1 :: Word8) >> put key >> put template
23+ put (EscapeCharacter template) = put (2 :: Word8) >> put template
24+ put (End) = put (3 :: Word8)
25+
26+ get = do tag <- getWord8
27+ case tag of 0 -> liftM2 Chunk get get
28+ 1 -> liftM2 Identifier get get
29+ 2 -> liftM EscapeCharacter get
30+ 3 -> return End
31+ _ -> error "Error reading template"