on master help sign in
6 files changed+59−46
since splitsnapshots
unifiedsplit
CHANGELOG.md+13 hakyll.cabal+1−1 lib/Hakyll/Web/Template/Context.hs+14−1 lib/Hakyll/Web/Template/Internal.hs+3−2 tests/Hakyll/Web/Tags/Tests.hs−42 tests/Hakyll/Web/Template/Context/Tests.hs+28
CHANGELOG.md+13
@@ -4,6 +4,19 @@ title: Releases
44
55# Releases
66
7+## Hakyll 4.13.0.0 (2019-08-30)
8+
9+- Improved documentation in many places (contribution by Bergi)
10+- Significantly improve error messages when reading and applying templates
11+ (contribution by Bergi)
12+ * `empty` and `fail` for `Compiler` now fail without or with a message,
13+ allowing for much better debug output
14+ * `renderFeed`, `renderRssWithTemplates` and `renderAtomWithTemplates` now
15+ take `Template` rather than `String` arguments
16+- Add option to specify date in directory structure,e.g.
17+ `posts/2019/05/10/tomorrow.md` (contribution by Taeer Bar-Ya)
18+- Bump QuickCheck to 2.13
19+
720## Hakyll 4.12.5.2 (2019-05-09)
821
922- Bump pandoc to 2.7
hakyll.cabal+1−1
@@ -1,5 +1,5 @@
11Name: hakyll
2−Version: 4.12.5.2
2+Version: 4.13.0.0
33
44Synopsis: A static website compiler library
55Description:
lib/Hakyll/Web/Template/Context.hs+14−1
@@ -21,6 +21,7 @@
2121--------------------------------------------------------------------------------
2222{-# LANGUAGE CPP #-}
2323{-# LANGUAGE ExistentialQuantification #-}
24+{-# LANGUAGE RankNTypes #-}
2425module Hakyll.Web.Template.Context
2526 ( ContextField (..)
2627 , Context (..)
@@ -48,6 +49,7 @@ module Hakyll.Web.Template.Context
4849 , teaserField
4950 , teaserFieldWithSeparator
5051 , missingField
52+ , bindItem
5153 ) where
5254
5355
@@ -176,7 +178,11 @@ listField key c xs = listFieldWith key c (const xs)
176178
177179
178180--------------------------------------------------------------------------------
179−-- | Creates a list field like 'listField', but supplies the current page
181+-- | Produces a new 'Context' which has list field 'key'. All fields from
182+-- 'c' are also accessible from the produced context.
183+-- Be careful when doing @listFieldWith k ca f <> cb@ as any fields in @ca@
184+-- will override fields in @cb@ with the same name.
185+-- Creates a list field like 'listField', but supplies the current page
180186-- to the compiler.
181187listFieldWith
182188 :: String -> Context a -> (Item b -> Compiler [Item a]) -> Context b
@@ -466,3 +472,10 @@ parseTimeM = TF.parseTimeM
466472#else
467473parseTimeM _ = TF.parseTime
468474#endif
475+
476+--------------------------------------------------------------------------------
477+
478+-- | Binds an 'Item' to a given 'Context', allowing it to be combined with any
479+-- other 'Context' of any type.
480+bindItem :: Context a -> Item a -> forall b. Context b
481+bindItem (Context ctx) ia = Context $ \k args _ -> ctx k args ia
lib/Hakyll/Web/Template/Internal.hs+3−2
@@ -21,7 +21,8 @@ module Hakyll.Web.Template.Internal
2121
2222
2323--------------------------------------------------------------------------------
24−import Control.Monad.Except (catchError)
24+import Control.Monad (forM)
25+import Control.Monad.Except (MonadError (..), catchError)
2526import Data.Binary (Binary)
2627import Data.List (intercalate)
2728import qualified Data.List.NonEmpty as NonEmpty
@@ -171,7 +172,7 @@ applyTemplate' tes context x = go tes
171172 StringField _ -> expected "list" "string" typeMsg
172173 ListField c xs -> withErrorMessage bodyMsg $ do
173174 sep <- maybe (return "") go s
174− bs <- mapM (applyTemplate' b c) xs
175+ bs <- forM xs $ applyTemplate' b $ c <> bindItem context x
175176 return $ intercalate sep bs
176177 where
177178 headMsg = "In expr '$for(" ++ show e ++ ")$'"
tests/Hakyll/Web/Tags/Tests.hsdeleted−42
@@ -1,42 +0,0 @@
1−--------------------------------------------------------------------------------
2−{-# LANGUAGE OverloadedStrings #-}
3−module Hakyll.Web.Tags.Tests
4− ( tests
5− ) where
6−
7−--------------------------------------------------------------------------------
8−import Test.Tasty (TestTree, testGroup)
9−import Test.Tasty.HUnit (Assertion, testCase, (@?=))
10−
11−--------------------------------------------------------------------------------
12−import Hakyll.Core.Identifier
13−import Hakyll.Core.Provider
14−import Hakyll.Core.Store (Store)
15−import Hakyll.Web.Tags
16−import TestSuite.Util
17−
18−tests :: TestTree
19−tests = testGroup "Hakyll.Web.Tags"
20− [ testCase "testGetCategory" testGetCategory
21− ]
22−
23−testGetCategory :: Assertion
24−testGetCategory = do
25− store <- newTestStore
26− provider <- newTestProvider store
27−
28− noCategory <- testCategoryDone store provider "example.md"
29− noCategory @?= [""]
30−
31− oneCategory1 <- testCategoryDone store provider "posts/2010-08-26-birthday.md"
32− oneCategory1 @?= ["posts"]
33−
34− oneCategory2 <- testCategoryDone store provider "posts/2019/05/10/tomorrow.md"
35− oneCategory2 @?= ["10"]
36−
37− cleanTestEnv
38−
39−--------------------------------------------------------------------------------
40−testCategoryDone :: Store -> Provider -> Identifier -> IO [String]
41−testCategoryDone store provider identifier =
42− testCompilerDone store provider identifier $ getCategory identifier
tests/Hakyll/Web/Template/Context/Tests.hs+28
@@ -13,9 +13,11 @@ import Test.Tasty.HUnit (Assertion, testCase, (@=?))
1313--------------------------------------------------------------------------------
1414import Hakyll.Core.Compiler
1515import Hakyll.Core.Identifier
16+import Hakyll.Core.Item
1617import Hakyll.Core.Provider
1718import Hakyll.Core.Store (Store)
1819import Hakyll.Web.Template.Context
20+import Hakyll.Web.Template.Internal
1921import TestSuite.Util
2022
2123
@@ -23,6 +25,7 @@ import TestSuite.Util
2325tests :: TestTree
2426tests = testGroup "Hakyll.Web.Template.Context.Tests"
2527 [ testCase "testDateField" testDateField
28+ , testCase "testOuerLoopContextAccess" testOuerLoopContextAccess
2629 ]
2730
2831
@@ -65,3 +68,28 @@ testContextDone store provider identifier key context =
6568 _ -> error $
6669 "Hakyll.Web.Template.Context.Tests.testContextDone: " ++
6770 "expected StringField"
71+
72+--------------------------------------------------------------------------------
73+
74+testOuerLoopContextAccess :: Assertion
75+testOuerLoopContextAccess = do
76+ store <- newTestStore
77+ provider <- newTestProvider store
78+ test store provider ctx "baz"
79+ test store provider (ctx' <> ctx) "not baz"
80+ test store provider (ctx <> ctx') "baz"
81+
82+ cleanTestEnv
83+ where
84+ tpl = readTemplate "$for(foo)$$for(bar)$$qux$$endfor$$endfor$"
85+ ctx = mconcat [
86+ field "qux" $ const $ return "baz"
87+ , listField "foo" (listField "bar" mempty $ return [mockItem])
88+ $ return [mockItem]
89+ ]
90+ ctx' = field "qux" $ const $ return "not baz"
91+ mockItem = Item "" ()
92+ test store provider context str = do
93+ str' <- testCompilerDone store provider ""
94+ $ applyTemplate tpl context mockItem
95+ str @=? itemBody str'