hastache-0.6.1: Haskell implementation of Mustache templates

Safe Haskell | None
Language | Haskell98

Text.Hastache.Context

Description

Hastache context helpers

Synopsis

- mkStrContext :: Monad m => (String -> MuType m) -> MuContext m
- mkStrContextM :: Monad m => (String -> m (MuType m)) -> MuContext m
- mkGenericContext :: (Monad m, Data a, Typeable m) => a -> MuContext m
- mkGenericContext' :: (Monad m, Data a, Typeable m) => (String -> String) -> Ext -> a -> MuContext m
- type Ext = forall b. (Data b, Typeable b) => b -> String
- defaultExt :: Ext

# Documentation

mkStrContext :: Monad m => (String -> MuType m) -> MuContext m #

Make Hastache context from String -> MuType function

mkStrContextM :: Monad m => (String -> m (MuType m)) -> MuContext m #

Make Hastache context from monadic String -> MuType function

mkGenericContext :: (Monad m, Data a, Typeable m) => a -> MuContext m #

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
- Version
- Maybe `a` (where `a` is a supported datatype)
- Either `a` `b` (where `a` and `b` are supported datatypes)
- Data.Text.Text -> Data.Text.Text
- Data.Text.Text -> Data.Text.Lazy.Text
- Data.Text.Lazy.Text -> Data.Text.Lazy.Text
- Data.ByteString.ByteString -> Data.ByteString.ByteString
- String -> String
- Data.ByteString.ByteString -> Data.ByteString.Lazy.ByteString
- MonadIO m => Data.Text.Text -> m Data.Text.Text
- MonadIO m => Data.Text.Text -> m Data.Text.Lazy.Text
- MonadIO m => Data.Text.Lazy.Text -> m Data.Text.Lazy.Text
- 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.Text as T
    import qualified Data.Text.Lazy as TL
    import qualified Data.Text.Lazy.IO as TL
    import Data.Data
    import Data.Generics
    import Data.Char

    data InternalData = InternalData {
        someField       :: String,
        anotherField    :: Int
        } deriving (Data, Typeable, Show)

    data Example = Example {
        stringField             :: String,
        intField                :: Int,
        dataField               :: InternalData,
        simpleListField         :: [String],
        dataListField           :: [InternalData],
        stringFunc              :: String -> String,
        textFunc                :: T.Text -> T.Text,
        monadicStringFunc       :: String -> IO String,
        monadicTextFunc         :: T.Text -> IO T.Text
        } deriving (Data, Typeable)

    example = hastacheStr defaultConfig (encodeStr template)
        (mkGenericContext context)
        where
        template = unlines [
            "string: {{stringField}}",
            "int: {{intField}}",
            "data: {{dataField.someField}}, {{dataField.anotherField}}",
            "data: {{#dataField}}{{someField}}, {{anotherField}}{{/dataField}}",
            "simple list: {{#simpleListField}}{{.}} {{/simpleListField}}",
            "data list:",
            "{{#dataListField}}",
            " * {{someField}}, {{anotherField}}. top level var: {{intField}}",
            "{{/dataListField}}",
            "{{#stringFunc}}upper{{/stringFunc}}",
            "{{#textFunc}}reverse{{/textFunc}}",
            "{{#monadicStringFunc}}upper (monadic){{/monadicStringFunc}}",
            "{{#monadicTextFunc}}reverse (monadic){{/monadicTextFunc}}"]
        context = Example { stringField = "string value", intField = 1,
            dataField = InternalData "val" 123, simpleListField = ["a","b","c"],
            dataListField = [InternalData "aaa" 1, InternalData "bbb" 2],
            stringFunc = map toUpper,
            textFunc = T.reverse,
            monadicStringFunc = return . map toUpper,
            monadicTextFunc = return . T.reverse }

    main = example >>= TL.putStrLn

Result:

    string: string value
    int: 1
    data: val, 123
    data: val, 123
    simple list: a b c
    data list:
     * aaa, 1. top level var: 1
     * bbb, 2. top level var: 1
    UPPER
    esrever
    UPPER (MONADIC)
    )cidanom( esrever

Hastache also supports datatypes with multiple constructors:

    data A = A { str :: String }
           | B { num :: Int }

    {{#A}}
    A : {{str}}
    {{/A}}
    {{#B}}
    B : {{num}}
    {{/B}}

mkGenericContext' :: (Monad m, Data a, Typeable m) => (String -> String) -> Ext -> a -> MuContext m #

Like `mkGenericContext`, but apply the first function to record field names when constructing the context. The second function is used to constructing values for context from datatypes that are nor supported as primitives in the library. The resulting value can be accessed using the `.DatatypeName` field:

    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TypeSynonymInstances #-}
    import Text.Hastache
    import Text.Hastache.Context

    import qualified Data.Text.Lazy as TL
    import qualified Data.Text.Lazy.IO as TL

    import Data.Data (Data, Typeable)
    import Data.Decimal
    import Data.Generics.Aliases (extQ)

    data Test = Test {n::Int, m::Decimal} deriving (Data, Typeable)
    deriving instance Data Decimal

    val :: Test
    val = Test 1 (Decimal 3 1500)

    q :: Ext
    q = defaultExt `extQ` ((i::Decimal) -> "A decimal: " ++ show i)

    r "m" = "moo"
    r x   = x

    example :: IO TL.Text
    example = hastacheStr defaultConfig
                          (encodeStr template)
                          (mkGenericContext' r q val)

    template = concat [
         "{{n}}\n",
         "{{moo.Decimal}}"
         ]

    main = example >>= TL.putStrLn

Result:

    1
    A decimal: 1.500

type Ext = forall b. (Data b, Typeable b) => b -> String #

defaultExt :: Ext #

`defaultExt ==` `gshow`