hastache 0.2.2 → 0.2.4
raw patch · 5 files changed
+314/−82 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.markdown +0/−13
- README.md +210/−0
- Text/Hastache.hs +29/−4
- Text/Hastache/Context.hs +71/−61
- hastache.cabal +4/−4
− README.markdown
@@ -1,13 +0,0 @@-# Hastache--Haskell implementation of [Mustache templates](http://mustache.github.com/)--## Installation-- cabal update- cabal install hastache--## Examples--See tests/test.hs for examples of usage-
+ README.md view
@@ -0,0 +1,210 @@+# Hastache++Haskell implementation of [Mustache templates](http://mustache.github.com/)++## Installation++ cabal update+ cabal install hastache++## Usage++Read [Mustache documentation](http://mustache.github.com/mustache.5.html) for template syntax.++### Examples++#### Variables++```haskell+import Text.Hastache +import Text.Hastache.Context +import qualified Data.ByteString.Lazy as LZ ++main = hastacheStr defaultConfig (encodeStr template) (mkStrContext context)+ >>= LZ.putStrLn++template = "Hello, {{name}}!\n\nYou have {{unread}} unread messages." ++context "name" = MuVariable "Haskell"+context "unread" = MuVariable (100 :: Int)+```++```+Hello, Haskell!++You have 100 unread messages.+```++With Generics++```haskell+{-# LANGUAGE DeriveDataTypeable #-}+import Text.Hastache +import Text.Hastache.Context +import qualified Data.ByteString.Lazy as LZ +import Data.Data +import Data.Generics ++main = hastacheStr defaultConfig (encodeStr template) context+ >>= LZ.putStrLn++data Info = Info { + name :: String, + unread :: Int + } deriving (Data, Typeable)++template = "Hello, {{name}}!\n\nYou have {{unread}} unread messages."+context = mkGenericContext $ Info "Haskell" 100+```++#### Lists++```haskell+template = concat [ + "{{#heroes}}\n", + "* {{name}} \n", + "{{/heroes}}\n"] ++context "heroes" = MuList $ map (mkStrContext . mkListContext) + ["Nameless","Long Sky","Flying Snow","Broken Sword","Qin Shi Huang"]+ where+ mkListContext name = \"name" -> MuVariable name+```++```+* Nameless +* Long Sky +* Flying Snow +* Broken Sword +* Qin Shi Huang+```++With Generics++```haskell+data Hero = Hero { name :: String } deriving (Data, Typeable)+data Heroes = Heroes { heroes :: [Hero] } deriving (Data, Typeable)++template = concat [ + "{{#heroes}}\n", + "* {{name}} \n", + "{{/heroes}}\n"] ++context = mkGenericContext $ Heroes $ map Hero ["Nameless","Long Sky",+ "Flying Snow","Broken Sword","Qin Shi Huang"]+```++Another Generics version++```haskell+data Heroes = Heroes { heroes :: [String] } deriving (Data, Typeable)++template = concat [ + "{{#heroes}}\n", + "* {{.}} \n", + "{{/heroes}}\n"] ++context = mkGenericContext $ Heroes ["Nameless","Long Sky","Flying Snow", + "Broken Sword","Qin Shi Huang"]+```++#### Functions++```haskell+template = "Hello, {{#reverse}}world{{/reverse}}!" ++context "reverse" = MuLambda (reverse . decodeStr)+```++```+Hello, dlrow!+```++#### Monadic functions++```haskell+{-# LANGUAGE FlexibleContexts #-}+import Text.Hastache +import Text.Hastache.Context +import qualified Data.ByteString.Lazy as LZ +import Control.Monad.State ++main = run >>= LZ.putStrLn++run = evalStateT stateFunc ""++stateFunc :: StateT String IO LZ.ByteString+stateFunc = + hastacheStr defaultConfig (encodeStr template) (mkStrContext context) ++template = "{{#arg}}aaa{{/arg}} {{#arg}}bbb{{/arg}} {{#arg}}ccc{{/arg}}"++context "arg" = MuLambdaM $ arg . decodeStr++arg :: MonadState String m => String -> m String+arg a = do + v <- get+ let nv = v ++ a+ put nv+ return nv+```++```+aaa aaabbb aaabbbccc+```++#### Generics big example++```haskell+data Book = Book { + title :: String, + publicationYear :: Integer + } deriving (Data, Typeable) + +data Life = Life { + born :: Integer, + died :: Integer + } deriving (Data, Typeable) + +data Writer = Writer { + name :: String, + life :: Life, + books :: [Book]+ } deriving (Data, Typeable) + +template = concat [ + "Name: {{name}} ({{life.born}} - {{life.died}})\n", + "{{#life}}\n", + "Born: {{born}}\n", + "Died: {{died}}\n", + "{{/life}}\n", + "Bibliography:\n", + "{{#books}}\n", + " {{title}} ({{publicationYear}})\n", + "{{/books}}\n"+ ]++context = mkGenericContext Writer { + name = "Mikhail Bulgakov", + life = Life 1891 1940, + books = [ + Book "Heart of a Dog" 1987, + Book "Notes of a country doctor" 1926, + Book "The Master and Margarita" 1967]+ }+```++```+Name: Mikhail Bulgakov (1891 - 1940)+Born: 1891+Died: 1940+Bibliography:+ Heart of a Dog (1987)+ Notes of a country doctor (1926)+ The Master and Margarita (1967)+```++#### More examples++ * [Hastache test](https://github.com/lymar/hastache/blob/master/tests/test.hs)+ * Real world example: [README.md file generator](https://github.com/lymar/hastache/blob/master/mkReadme.hs)
Text/Hastache.hs view
@@ -16,26 +16,51 @@ Simplest example: @-module Main where - import Text.Hastache import Text.Hastache.Context import qualified Data.ByteString.Lazy as LZ - + main = do res <- hastacheStr defaultConfig (encodeStr template) (mkStrContext context) LZ.putStrLn res where - template = \"Hello, {{name}}!\" + template = \"Hello, {{name}}!\\n\\nYou have {{unread}} unread messages.\" context \"name\" = MuVariable \"Haskell\"+ context \"unread\" = MuVariable (100 :: Int) @ Result: @ Hello, Haskell!++You have 100 unread messages. @++Using Generics:++@+import Text.Hastache +import Text.Hastache.Context +import qualified Data.ByteString.Lazy as LZ +import Data.Data +import Data.Generics + +data Info = Info { + name :: String, + unread :: Int + } deriving (Data, Typeable)++main = do + res <- hastacheStr defaultConfig (encodeStr template) + (mkGenericContext inf) + LZ.putStrLn res + where + template = \"Hello, {{name}}!\\n\\nYou have {{unread}} unread messages.\"+ inf = Info \"Haskell\" 100+@+ -} module Text.Hastache ( hastacheStr
Text/Hastache/Context.hs view
@@ -37,7 +37,71 @@ {- | Make Hastache context from Data.Data deriving type +Supported field types:++ * String+ + * Char+ + * Double++ * Float++ * Int++ * Int8++ * Int16++ * Int32++ * Int64++ * Integer++ * Word++ * Word8++ * Word16++ * Word32++ * Word64++ * Data.ByteString.ByteString++ * Data.ByteString.Lazy.ByteString+ + * Data.Text.Text++ * Data.Text.Lazy.Text+ + * Bool+ + * Data.ByteString.ByteString -> Data.ByteString.ByteString+ + * String -> String+ + * Data.ByteString.ByteString -> Data.ByteString.Lazy.ByteString+ + * MonadIO m => Data.ByteString.ByteString -> m Data.ByteString.ByteString+ + * MonadIO m => String -> m String+ + * MonadIO m => Data.ByteString.ByteString -> m Data.ByteString.Lazy.ByteString++Example:+ @+import Text.Hastache +import Text.Hastache.Context +import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as LZ +import Data.Data +import Data.Generics +import Data.Char+ data InternalData = InternalData { someField :: String, anotherField :: Int@@ -50,9 +114,9 @@ simpleListField :: [String], dataListField :: [InternalData], stringFunc :: String -> String,- byteStringFunc :: Data.ByteString.ByteString -> Data.ByteString.ByteString,+ byteStringFunc :: B.ByteString -> B.ByteString, monadicStringFunc :: String -> IO String,- monadicByteStringFunc :: Data.ByteString.ByteString -> IO Data.ByteString.ByteString+ monadicByteStringFunc :: B.ByteString -> IO B.ByteString } deriving (Data, Typeable) example = hastacheStr defaultConfig (encodeStr template) @@ -75,12 +139,12 @@ context = Example { stringField = \"string value\", intField = 1, dataField = InternalData \"val\" 123, simpleListField = [\"a\",\"b\",\"c\"], dataListField = [InternalData \"aaa\" 1, InternalData \"bbb\" 2],- stringFunc = map Data.Char.toUpper,- byteStringFunc = Data.ByteString.reverse,- monadicStringFunc = return . map Data.Char.toUpper,- monadicByteStringFunc = return . Data.ByteString.reverse }+ stringFunc = map toUpper,+ byteStringFunc = B.reverse,+ monadicStringFunc = return . map toUpper,+ monadicByteStringFunc = return . B.reverse } -main = example >>= Data.ByteString.Lazy.putStrLn+main = example >>= LZ.putStrLn @ Result:@@ -100,60 +164,6 @@ )cidanom( esrever @ -Supported field types:-- * String- - * Char- - * Double-- * Float-- * Int-- * Int8-- * Int16-- * Int32-- * Int64-- * Integer-- * Word-- * Word8-- * Word16-- * Word32-- * Word64-- * Data.ByteString.ByteString-- * Data.ByteString.Lazy.ByteString- - * Data.Text.Text-- * Data.Text.Lazy.Text- - * Bool- - * Data.ByteString.ByteString -> Data.ByteString.ByteString- - * String -> String- - * Data.ByteString.ByteString -> Data.ByteString.Lazy.ByteString- - * MonadIO m => Data.ByteString.ByteString -> m Data.ByteString.ByteString- - * MonadIO m => String -> m String- - * MonadIO m => Data.ByteString.ByteString -> m Data.ByteString.Lazy.ByteString- -} mkGenericContext :: (Monad m, Data a, Typeable1 m) => a -> MuContext m mkGenericContext val = toGenTemp val ~> convertGenTempToContext
hastache.cabal view
@@ -1,5 +1,5 @@ name: hastache-version: 0.2.2+version: 0.2.4 license: BSD3 license-file: LICENSE category: Text@@ -17,13 +17,13 @@ Haskell implementation of Mustache templates (<http://mustache.github.com/>). . See homepage for examples of usage: <http://github.com/lymar/hastache>-+ extra-source-files: tests/partFile tests/RunTest.sh tests/test.hs- README.markdown- + README.md+ library exposed-modules: Text.Hastache