Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Accessing array item by index

  • Loading branch information...
commit 1eee5ad326df674b07f5001cbb58c18dab878ba9 1 parent d0dfe83
Sergey Lymar lymar authored
Showing with 87 additions and 3 deletions.
  1. +31 −3 Text/Hastache.hs
  2. +56 −0 tests/test.hs
34 Text/Hastache.hs
View
@@ -85,6 +85,7 @@ import Control.Monad.Reader (ask, runReaderT, MonadReader, ReaderT)
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.Maybe (isJust)
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)
@@ -274,9 +275,28 @@ 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 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 = encodeStr "."
+
findCloseSection ::
ByteString
-> ByteString
@@ -358,8 +378,16 @@ renderBlock contexts symb inTag afterClose otag ctag conf
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
56 tests/test.hs
View
@@ -303,6 +303,7 @@ genericContextTest = do
\{{#someDataList}}\n\
\* {{.}} \n\
\{{/someDataList}}\n\
+ \List item by index: {{someDataList.1}} \n\
\Obj list:\n\
\{{#someDataObjList}}\n\
\* {{intDataField1}} : {{intDataField2}} \n\
@@ -335,6 +336,7 @@ genericContextTest = do
\* 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 @@ nestedGenericContextTest = do
\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 @@ tests = TestList [
,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
Please sign in to comment.
Something went wrong with that request. Please try again.