on master help sign in
Rewrite template application
commit4cb6f9241435fae7a23a7f9fbbdab99e65285eff authorJasper Van der Jeugt <m@jaspervdj.be> dateFri 9 Nov 2012, 18:13 (14 years ago) parent2834fd9
7 files changed+92−72
src/Hakyll/Core/Compiler.hs−7 src/Hakyll/Core/Compiler/Internal.hs+6 src/Hakyll/Core/Util/Arrow.hs+26−11 src/Hakyll/Web/Feed.hs+2−2 src/Hakyll/Web/Page/List.hs+2−2 src/Hakyll/Web/Tags.hs+3−3 src/Hakyll/Web/Template.hs+53−47
src/Hakyll/Core/Compiler.hs−7
@@ -108,7 +108,6 @@ module Hakyll.Core.Compiler
108108 , cached
109109 , unsafeCompiler
110110 , traceShowCompiler
111− , mapCompiler
112111 , timedCompiler
113112 , byPattern
114113 , byExtension
@@ -328,12 +327,6 @@ traceShowCompiler = fromJob $ \x -> CompilerM $ do
328327 report logger $ show x
329328 return x
330329
331−-- | Map over a compiler
332−--
333−mapCompiler :: Compiler a b
334− -> Compiler [a] [b]
335−mapCompiler (Compiler d j) = Compiler d $ mapM j
336−
337330-- | Log and time a compiler
338331--
339332timedCompiler :: String -- ^ Message
src/Hakyll/Core/Compiler/Internal.hs+6
@@ -38,6 +38,7 @@ import Hakyll.Core.Logger
3838import Hakyll.Core.ResourceProvider
3939import Hakyll.Core.Routes
4040import Hakyll.Core.Store
41+import Hakyll.Core.Util.Arrow
4142
4243
4344--------------------------------------------------------------------------------
@@ -138,6 +139,11 @@ instance ArrowChoice Compiler where
138139 Right r -> Right <$> return r
139140
140141
142+--------------------------------------------------------------------------------
143+instance ArrowMap Compiler where
144+ mapA (Compiler d j) = Compiler d $ mapM j
145+
146+
141147--------------------------------------------------------------------------------
142148-- | Run a compiler, yielding the resulting target
143149runCompilerJob :: Compiler () a -- ^ Compiler to run
src/Hakyll/Core/Util/Arrow.hs+26−11
@@ -1,25 +1,40 @@
1+--------------------------------------------------------------------------------
12-- | Various arrow utility functions
2−--
33module Hakyll.Core.Util.Arrow
4− ( constA
4+ ( ArrowMap (..)
5+ , constA
56 , sequenceA
67 , unitA
78 ) where
89
9−import Control.Arrow (Arrow, (&&&), arr, (>>^))
1010
11−constA :: Arrow a
12− => c
13− -> a b c
11+--------------------------------------------------------------------------------
12+import Control.Arrow (Arrow, ArrowChoice, arr, (&&&), (>>^))
13+
14+
15+--------------------------------------------------------------------------------
16+-- | Additional arrow typeclass for performance reasons.
17+class ArrowChoice a => ArrowMap a where
18+ mapA :: a b c -> a [b] [c]
19+
20+
21+--------------------------------------------------------------------------------
22+instance ArrowMap (->) where
23+ mapA = map
24+
25+
26+--------------------------------------------------------------------------------
27+constA :: Arrow a => c -> a b c
1428constA = arr . const
1529
16−sequenceA :: Arrow a
17− => [a b c]
18− -> a b [c]
30+
31+--------------------------------------------------------------------------------
32+sequenceA :: Arrow a => [a b c] -> a b [c]
1933sequenceA = foldr reduce $ constA []
2034 where
2135 reduce xa la = xa &&& la >>^ arr (uncurry (:))
2236
23−unitA :: Arrow a
24− => a b ()
37+
38+--------------------------------------------------------------------------------
39+unitA :: Arrow a => a b ()
2540unitA = constA ()
src/Hakyll/Web/Feed.hs+2−2
@@ -62,7 +62,7 @@ createFeed :: Template -- ^ Feed template
6262 -> [Page String] -- ^ Items to include
6363 -> String -- ^ Resulting feed
6464createFeed feedTemplate itemTemplate url configuration items =
65− pageBody $ applyTemplate feedTemplate
65+ pageBody $ applyTemplateToPage feedTemplate
6666 $ trySetField "updated" updated
6767 $ trySetField "title" (feedTitle configuration)
6868 $ trySetField "description" (feedDescription configuration)
@@ -73,7 +73,7 @@ createFeed feedTemplate itemTemplate url configuration items =
7373 $ fromBody body
7474 where
7575 -- Preprocess items
76− items' = flip map items $ applyTemplate itemTemplate
76+ items' = flip map items $ applyTemplateToPage itemTemplate
7777 . trySetField "root" (feedRoot configuration)
7878
7979 -- Body: concatenated items
src/Hakyll/Web/Page/List.hs+2−2
@@ -55,8 +55,8 @@ pageListCompiler sort template =
5555--
5656applyTemplateToList :: Identifier Template
5757 -> Compiler [Page String] [Page String]
58−applyTemplateToList identifier =
59− require identifier $ \posts template -> map (applyTemplate template) posts
58+applyTemplateToList identifier = require identifier $
59+ \posts template -> map (applyTemplateToPage template) posts
6060
6161-- | Concatenate the bodies of a page list
6262--
src/Hakyll/Web/Tags.hs+3−3
@@ -65,6 +65,7 @@ import Hakyll.Web.Urls
6565import Hakyll.Core.Writable
6666import Hakyll.Core.Identifier
6767import Hakyll.Core.Compiler
68+import Hakyll.Core.Util.Arrow
6869import Hakyll.Core.Util.String
6970
7071-- | Data about tags
@@ -128,8 +129,7 @@ renderTags :: (String -> Identifier (Page a))
128129 -- ^ Tag cloud renderer
129130renderTags makeUrl makeItem concatItems = proc (Tags tags) -> do
130131 -- In tags' we create a list: [((tag, route), count)]
131− tags' <- mapCompiler ((id &&& (getRouteFor <<^ makeUrl)) *** arr length)
132− -< tags
132+ tags' <- mapA ((id &&& (getRouteFor <<^ makeUrl)) *** arr length) -< tags
133133
134134 let -- Absolute frequencies of the pages
135135 freqs = map snd tags'
@@ -195,7 +195,7 @@ renderTagsFieldWith tags destination makeUrl =
195195 -- Compiler creating a comma-separated HTML string for a list of tags
196196 renderTags' :: Compiler [String] String
197197 renderTags' = arr (map $ id &&& makeUrl)
198− >>> mapCompiler (id *** getRouteFor)
198+ >>> mapA (id *** getRouteFor)
199199 >>> arr (map $ uncurry renderLink)
200200 >>> arr (renderHtml . mconcat . intersperse ", " . catMaybes)
201201
src/Hakyll/Web/Template.hs+53−47
@@ -58,66 +58,78 @@
5858-- > <a href="/about.html"> About
5959-- > <a href="/code.html"> Code
6060-- > #{body}
61−--
61+{-# LANGUAGE Arrows #-}
62+{-# LANGUAGE ScopedTypeVariables #-}
6263module Hakyll.Web.Template
6364 ( Template
6465 , applyTemplate
65− , applyTemplateWith
66+ , applyTemplateToPage
6667 , applySelf
6768 , templateCompiler
6869 , templateCompilerWith
6970 , applyTemplateCompiler
70− , applyTemplateCompilerWith
7171 ) where
7272
73−import Control.Arrow
74−import Data.Maybe (fromMaybe)
75−import System.FilePath (takeExtension)
76−import qualified Data.Map as M
7773
78−import Text.Hamlet (HamletSettings, defaultHamletSettings)
74+--------------------------------------------------------------------------------
75+import Control.Arrow
76+import Control.Category (id)
77+import qualified Data.Map as M
78+import Data.Maybe (fromMaybe)
79+import Prelude hiding (id)
80+import System.FilePath (takeExtension)
81+import Text.Hamlet (HamletSettings,
82+ defaultHamletSettings)
7983
80−import Hakyll.Core.Compiler
81−import Hakyll.Core.Identifier
82−import Hakyll.Web.Template.Internal
83−import Hakyll.Web.Template.Read
84−import Hakyll.Web.Page.Internal
84+--------------------------------------------------------------------------------
85+import Hakyll.Core.Compiler
86+import Hakyll.Core.Identifier
87+import Hakyll.Core.Util.Arrow
88+import Hakyll.Web.Page.Internal
89+import Hakyll.Web.Template.Internal
90+import Hakyll.Web.Template.Read
8591
86−-- | Substitutes @$identifiers@ in the given @Template@ by values from the given
87−-- "Page". When a key is not found, it is left as it is.
88−--
89−applyTemplate :: Template -> Page String -> Page String
90−applyTemplate = applyTemplateWith defaultMissingHandler
9192
92−-- | Default solution if a key is missing: render it again
93−defaultMissingHandler :: String -> String
94−defaultMissingHandler k = "$" ++ k ++ "$"
93+--------------------------------------------------------------------------------
94+applyTemplate :: forall a b. (ArrowChoice a, ArrowMap a)
95+ => a (String, b) String
96+ -> a (Template, b) String
97+applyTemplate field =
98+ arr (\(tpl, x) -> [(e, x) | e <- unTemplate tpl]) >>>
99+ mapA applyElement >>^ concat
100+ where
101+ applyElement :: a (TemplateElement, b) String
102+ applyElement = unElement >>> (id ||| field)
95103
96−-- | A version of 'applyTemplate' which allows you to give a fallback option,
97−-- which can produce the value for a key if it is missing.
98−--
99−applyTemplateWith :: (String -> String) -- ^ Fallback if key missing
100− -> Template -- ^ Template to apply
101− -> Page String -- ^ Input page
102− -> Page String -- ^ Resulting page
103−applyTemplateWith missing template page =
104− fmap (const $ substitute =<< unTemplate template) page
104+ unElement :: a (TemplateElement, b) (Either String (String, b))
105+ unElement = arr $ \(e, x) -> case e of
106+ Chunk c -> Left c
107+ Escaped -> Left "$"
108+ Key k -> Right (k, x)
109+
110+
111+--------------------------------------------------------------------------------
112+-- | TODO: Remove
113+applyTemplateToPage :: Template -> Page String -> Page String
114+applyTemplateToPage tpl page =
115+ fmap (const $ applyTemplate pageField (tpl, page)) page
105116 where
106− map' = toMap page
107− substitute (Chunk chunk) = chunk
108− substitute (Key key) = fromMaybe (missing key) $ M.lookup key map'
109− substitute (Escaped) = "$"
117+ pageField (k, p) = fromMaybe ("$" ++ k ++ "$") $ M.lookup k $ toMap p
118+{-# DEPRECATED applyTemplateToPage "Use applyTemplate" #-}
119+
110120
121+--------------------------------------------------------------------------------
111122-- | Apply a page as it's own template. This is often very useful to fill in
112123-- certain keys like @$root@ and @$url@.
113−--
114124applySelf :: Page String -> Page String
115−applySelf page = applyTemplate (readTemplate $ pageBody page) page
125+applySelf page = applyTemplateToPage (readTemplate $ pageBody page) page
126+{-# DEPRECATED applySelf "Use applyTemplate" #-}
127+
116128
129+--------------------------------------------------------------------------------
117130-- | Read a template. If the extension of the file we're compiling is
118131-- @.hml@ or @.hamlet@, it will be considered as a Hamlet template, and parsed
119132-- as such.
120−--
121133templateCompiler :: Compiler () Template
122134templateCompiler = templateCompilerWith defaultHamletSettings
123135
@@ -135,15 +147,9 @@ templateCompilerWith settings =
135147 -- Hakyll template
136148 else readTemplate string
137149
150+
151+--------------------------------------------------------------------------------
138152applyTemplateCompiler :: Identifier Template -- ^ Template
139153 -> Compiler (Page String) (Page String) -- ^ Compiler
140−applyTemplateCompiler = applyTemplateCompilerWith defaultMissingHandler
141−
142−-- | A version of 'applyTemplateCompiler' which allows you to pass a function
143−-- which is called for a key when it is missing.
144−--
145−applyTemplateCompilerWith :: (String -> String)
146− -> Identifier Template
147− -> Compiler (Page String) (Page String)
148−applyTemplateCompilerWith missing identifier =
149− require identifier (flip $ applyTemplateWith missing)
154+applyTemplateCompiler identifier = require identifier $
155+ flip applyTemplateToPage