packages feed

hastache 0.3.3 → 0.4.1

raw patch · 4 files changed

+193/−16 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -11,6 +11,8 @@  Read [Mustache documentation](http://mustache.github.com/mustache.5.html) for template syntax. +See [Hastache hackage page](http://hackage.haskell.org/package/hastache).+ ### Examples  #### Variables@@ -106,6 +108,92 @@  context = mkGenericContext $ Heroes ["Nameless","Long Sky","Flying Snow",      "Broken Sword","Qin Shi Huang"]+```++List item by index++```haskell+main = mapM_ (\(template,context) ->+    hastacheStr defaultConfig (encodeStr template) context >>= LZ.putStrLn) +        [(template1, mkStrContext context1),+         (template1, context2),+         (template2, context3)]++names = ["Nameless","Long Sky","Flying Snow","Broken Sword","Qin Shi Huang"]++template1 = concat [+    "{{heroes.1.name}}\n",+    "{{heroes.0.name}}\n"]++-- Context as function+context1 "heroes" = MuList $ map (mkStrContext . mkListContext) names+    where+    mkListContext name = \"name" -> MuVariable name+context1 _ = MuNothing++-- With Generics+data Hero = Hero { name :: String } deriving (Data, Typeable)+data Heroes = Heroes { heroes :: [Hero] } deriving (Data, Typeable)++context2 = mkGenericContext $ Heroes $ map Hero names++template2 = concat [+    "{{heroName.3}}\n",+    "{{heroName.2}}\n"]++data HeroesStr = HeroesStr { heroName :: [String] } deriving (Data, Typeable)++context3 = mkGenericContext $ HeroesStr names+```++```+Long Sky+Nameless++Long Sky+Nameless++Broken Sword+Flying Snow+```++#### Conditional evaluation++Boolean++```haskell+template = "{{#boolean}}true{{/boolean}}{{^boolean}}false{{/boolean}}"+context "boolean" = MuBool False+```+```+false+```++List++```haskell+template = "{{^messages}}No new messages{{/messages}}"+context "messages" = MuList []+```+```+No new messages+```++Number++```haskell+main = mapM_ (\ctx ->+    hastacheStr defaultConfig (encodeStr template) (mkStrContext ctx)+    >>= LZ.putStrLn) [context1,context2]++template = "{{#msg}}{{msg}}{{/msg}}{{^msg}}No{{/msg}} new messages."++context1 "msg" = MuVariable (100 :: Int)+context2 "msg" = MuVariable (0 :: Int)+```+```+100 new messages.+No new messages. ```  #### Functions
Text/Hastache.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE ExistentialQuantification, FlexibleInstances, -    IncoherentInstances #-}+{-# LANGUAGE ExistentialQuantification, FlexibleInstances, IncoherentInstances,+             OverloadedStrings #-} -- Module:      Text.Hastache -- Copyright:   Sergey S Lymar (c) 2011  -- License:     BSD3@@ -85,6 +85,7 @@ import Control.Monad.Trans (lift, liftIO, MonadIO) import Data.AEq ((~==)) import Data.ByteString hiding (map, foldl1)+import Data.ByteString.Char8 (readInt) import Data.Char (ord) import Data.Int import Data.IORef@@ -92,7 +93,7 @@ import Data.Monoid (mappend, mempty) import Data.Word import Prelude hiding (putStrLn, readFile, length, drop, tail, dropWhile, elem,-    head, last, reverse, take, span)+    head, last, reverse, take, span, null) import System.Directory (doesFileExist) import System.FilePath (combine) @@ -243,9 +244,9 @@     muTemplateFileExt = Nothing     }  -defOTag = encodeStr "{{"-defCTag = encodeStr "}}"-unquoteCTag = encodeStr "}}}"+defOTag = "{{" :: ByteString+defCTag = "}}" :: ByteString+unquoteCTag = "}}}" :: ByteString  findBlock ::         ByteString @@ -269,14 +270,39 @@ toLBS :: ByteString -> LZ.ByteString toLBS v = LZ.fromChunks [v] ++readVar :: MonadIO m => [MuContext m] -> ByteString -> LZ.ByteString readVar [] _ = LZ.empty readVar (context:parentCtx) name =     case context name of         MuVariable a -> toLByteString a         MuBool a -> show a ~> encodeStr ~> toLBS-        MuNothing -> readVar parentCtx name+        MuNothing -> case tryFindArrayItem context name of+            Just (nctx,nn) -> readVar [nctx] nn+            _ -> readVar parentCtx name         _ -> LZ.empty +tryFindArrayItem :: MonadIO m => +       MuContext m+    -> ByteString +    -> Maybe (MuContext m, ByteString)+tryFindArrayItem context name = do+    guard $ length idx > 1+    (idx,nxt) <- readInt $ tail idx+    guard $ idx >= 0+    guard $ (null nxt) || ((head nxt) == (ord8 '.'))+    case context nm of+        MuList l -> do+            guard $ idx < (List.length l)+            let ncxt = l !! idx+            if null nxt +                then Just (ncxt, dotStr) -- {{some.0}}+                else Just (ncxt, tail nxt) -- {{some.0.field}}+        _ -> Nothing+    where+    (nm,idx) = breakSubstring dotStr name+    dotStr = "."+ findCloseSection ::         ByteString      -> ByteString @@ -287,11 +313,11 @@     guard (length after > 0)     Just (before, drop (length close) after)     where-    close = foldl1 append [otag, encodeStr "/", name, ctag]+    close = foldl1 append [otag, "/", name, ctag]     (before, after) = breakSubstring close str  trimCharsTest :: Word8 -> Bool-trimCharsTest = (`elem` encodeStr " \t")+trimCharsTest = (`elem` " \t")  trimAll :: ByteString -> ByteString trimAll str = span trimCharsTest str ~> snd ~> spanEnd trimCharsTest ~> fst@@ -312,7 +338,7 @@  processBlock :: MonadIO m =>         ByteString -    -> [ByteString -> MuType m] +    -> [MuContext m]      -> ByteString      -> ByteString      -> MuConfig @@ -326,8 +352,8 @@             addResBS str             return () -renderBlock:: MonadIO m =>-       [ByteString -> MuType m] +renderBlock :: MonadIO m =>+       [MuContext m]      -> Word8      -> ByteString      -> ByteString @@ -358,8 +384,16 @@                             then dropNL afterSection'                             else afterSection'                     tlInTag = tail inTag-                    readContext = map ($ tlInTag) contexts +                    readContext' = map ($ tlInTag) contexts                          ~> List.find (not . isMuNothing)+                    readContextWithIdx = do+                        Just (ctx,name) <- map (+                            \c -> tryFindArrayItem c tlInTag) +                            contexts ~> List.find isJust+                        Just $ ctx name+                    readContext = case readContext' of+                        Just a -> Just a+                        Nothing -> readContextWithIdx                     processAndNext = do                          processBlock sectionContent contexts otag ctag conf                         next afterSection
hastache.cabal view
@@ -1,9 +1,9 @@ name:            hastache-version:         0.3.3+version:         0.4.1 license:         BSD3 license-file:    LICENSE category:        Text-copyright:       Sergey S Lymar (c) 2011+copyright:       Sergey S Lymar (c) 2011-2012 author:          Sergey S Lymar <sergey.lymar@gmail.com> maintainer:      Sergey S Lymar <sergey.lymar@gmail.com> stability:       experimental@@ -45,4 +45,3 @@ source-repository head   type:     git   location: http://github.com/lymar/hastache-
tests/test.hs view
@@ -303,6 +303,7 @@         \{{#someDataList}}\n\         \* {{.}} \n\         \{{/someDataList}}\n\+        \List item by index: {{someDataList.1}} \n\         \Obj list:\n\         \{{#someDataObjList}}\n\         \* {{intDataField1}} : {{intDataField2}} \n\@@ -335,6 +336,7 @@         \* 1 \n\         \* 2 \n\         \* 3 \n\+        \List item by index: 2 \n\         \Obj list:\n\         \* a : 1 \n\         \* b : 2 \n\@@ -411,6 +413,57 @@         \Nested variable : NESTED_TWO\n\         \" +-- Accessing array item by index+arrayItemsTest = do+    res <- hastacheStr defaultConfig (encodeStr template) +        (mkStrContext context)+    assertEqualStr resCorrectness (decodeStrLBS res) testRes+    where+    template = "\+        \{{section.0.name}} {{section.1.name}} {{section.2.name}}\n\+        \{{#flags.0.val}}yes{{/flags.0.val}}\n\+        \{{^flags.1.val}}no{{/flags.0.val}}\n\+        \"+    context "section" = MuList $ map nameCtx ["Neo", "Morpheus", "Trinity"]+    context "flags" = MuList $ map flagCtx [True, False]+    context n = MuNothing+    nameCtx name = mkStrContext (\"name" -> MuVariable name)+    flagCtx val = mkStrContext (\"val" -> MuBool val)++    testRes = "\+        \Neo Morpheus Trinity\n\+        \yes\n\+        \no\n\+        \"++-- Accessing array item by index (generic version)+data ArrayItemTest_Item = ArrayItemTest_Item { +    name :: String +    } deriving (Data, Typeable)    ++data ArrayItemTest_Container = ArrayItemTest_Container { +    items       :: [ArrayItemTest_Item],+    itemsStr    :: [String]+    } deriving (Data, Typeable)    ++arrayItemsTestGeneric = do+    res <- hastacheStr defaultConfig (encodeStr template) context+    assertEqualStr resCorrectness (decodeStrLBS res) testRes+    where+    template = "\+        \{{items.0.name}} {{items.2.name}}\n\+        \{{itemsStr.0}} {{itemsStr.1}}\n\+        \"+    context = mkGenericContext $ ArrayItemTest_Container {+        items = [ArrayItemTest_Item "Bob", ArrayItemTest_Item "Alice",+                 ArrayItemTest_Item "Zoe"],+        itemsStr = ["Bob", "Alice", "Zoe"]+    }+    testRes = "\+        \Bob Zoe\n\+        \Bob Alice\n\+        \"+ tests = TestList [      TestLabel "Comments test" (TestCase commentsTest)     ,TestLabel "Variables test" (TestCase variablesTest)@@ -424,6 +477,9 @@     ,TestLabel "Generic context test" (TestCase genericContextTest)     ,TestLabel "Nested context test" (TestCase nestedContextTest)     ,TestLabel "Nested generic context test" (TestCase nestedGenericContextTest)+    ,TestLabel "Accessing array item by index" (TestCase arrayItemsTest)+    ,TestLabel "Accessing array item by index (generic version)" +        (TestCase arrayItemsTestGeneric)     ]  main = do