Orasund / elm-handlebars / Handlebars.Expression

A Handlebar template is composed out of expression.


type alias BlockHelper =
{ arg : Handlebars.Value.Value
, throw : String -> Error
, content : Handlebars.Path.Path -> Result Error String } -> Handlebars.Path.Path -> Result Error Strin
}

Block Helper


type alias Config =
{ expHelpers : Dict String ExpHelper
, blockHelpers : Dict String BlockHelper
, root : Handlebars.Path.Path 
}

The config can be used to extend the helpers.


type Error
    = StringExpected (( SubExp, Handlebars.Value.Value ))
    | CollectionExpected Handlebars.Path.Path Handlebars.Path.RelativePath
    | BlockHelperNotFound String
    | FromBlockHelper ({ helper : String, error : String })
    | PathNotValid Handlebars.Path.Path Handlebars.Path.RelativePath
    | PathNotFound Handlebars.Path.Path
    | HelperNotFound String
    | FromHelper ({ helper : String, error : String })

Evaluation Errors


type alias ExpHelper =
List Handlebars.Value.Value -> Result String Handlebars.Value.Value

Expression Helper


type Expression
    = Text String
    | Variable SubExp
    | For Handlebars.Path.RelativePath (List Expression)
    | Block String SubExp (List Expression)

Expression


type SubExp
    = LookUp Handlebars.Path.RelativePath
    | Helper String (( SubExp, List SubExp ))

Sub expressions

evalExp : Config -> Expression -> Handlebars.Value.Value -> Result Error String

Evaluate a value based on a template

import Dict
import Handlebars.Value exposing (Value(..))
import Handlebars
import Array

jack : Value
jack =
    StringValue "jack"

value : Value
value =
    [ ( "name", jack )
    , ( "key", StringValue "name" )
    , ( "valid", BooleanValue True)
    , ( "people",
        [ StringValue "jack" , StringValue "gill" ]
        |> Array.fromList
        |> ArrayValue
    )
    ]
        |> Dict.fromList
        |> ObjectValue

evalExp Handlebars.defaultConfig
    ("Hello World"
        |> Text
    )
    value
    --> Ok "Hello World"

evalExp Handlebars.defaultConfig
    ( (0,["name"])
        |> LookUp
        |> Variable
    )
    value
    --> Ok "jack"

evalExp Handlebars.defaultConfig
    ( Helper "equals"
        ( LookUp (0,[ "name"])
        , [ LookUp (0,[ "key"]) ]
        )
        |> Variable
    )
    value
    |> (\err ->
        case err of
            Err (StringExpected _) ->
                False
            _ ->
                True
        )
    --> False

evalExp Handlebars.defaultConfig
    ( For (0,["people"])
        [(0,[ "@index"]) |> LookUp |> Variable]
    )
    value
    --> Ok "01"

evalExp Handlebars.defaultConfig
    ( For (0,[])
        [ "+" |> Text]
    )
    value
    --> Ok "++++"

evalExp Handlebars.defaultConfig
    ( For (0,["doesNotExist"])
        ["Success" |> Text]
    )
    value
    |> (\err ->
        case err of
            Err (PathNotFound _) ->
                False
            _ ->
                True
        )
    --> False

evalExp Handlebars.defaultConfig
    ( For (0,["..notValid.."])
        ["Success" |> Text]
    )
    value
    |> (\err ->
        case err of
            Err (PathNotFound _) ->
                False
            _ ->
                True
        )
    --> False

evalExp Handlebars.defaultConfig
    ( For (42,[])
        ["Success" |> Text]
    )
    value
    |> (\err ->
        case err of
            Err (PathNotValid _ _) ->
                False
            _ ->
                True
        )
    --> False

evalExp Handlebars.defaultConfig
    ( For (0,["valid"])
        ["Success" |> Text]
    )
    value
    |> (\err ->
        case err of
            Err (CollectionExpected _ _) ->
                False
            _ ->
                True
        )
    --> False

evalExp Handlebars.defaultConfig
    ( Block "if" (LookUp (0,["valid"]))
        [Text "Hello"]
    )
    value
    --> Ok "Hello"

evalExp Handlebars.defaultConfig
    ( Block "invalid" (LookUp (0,[]))
        [Text "Hello"]
    )
    value
    --> Err (BlockHelperNotFound "invalid")

evalSubExp : Config -> Handlebars.Value.Value -> SubExp -> Result Error Handlebars.Value.Value

Evaluate a subexpression

import Dict
import Handlebars exposing (defaultConfig)
import Handlebars.Value exposing (Value(..))

expression : Expression
expression =
    Text ""

jack : Value
jack =
    StringValue "jack"

value : Value
value =
    [ ( "name", jack )
    , ( "key", StringValue "name" )
    ]
        |> Dict.fromList
        |> ObjectValue

Simplest subexpression is a look up to a relative path.

LookUp (0,["name"])
    |> evalSubExp defaultConfig value
    --> Ok jack

LookUp (0,["job"])
    |> evalSubExp defaultConfig  value
    --> Err (PathNotFound ["job"])

LookUp (1,[])
    |> evalSubExp defaultConfig value
    --> Err (PathNotValid [] (1,[]))

LookUp (1,[])
    |> evalSubExp {defaultConfig | root = ["name"]} value
    --> Ok value

Helper can also be used inside of subexpression.

Helper "lookup" ( LookUp (0,[]), [LookUp (0,[ "key" ])] )
    |> evalSubExp defaultConfig value
    --> Ok jack

Helper "lookup" ( LookUp (0,[ "name"]), [LookUp (0,[ "key" ])] )
    |> evalSubExp defaultConfig value
    |> (\err ->
        case err of
            Err (FromHelper args) ->
                args.helper == "lookup"
            _ ->
                False
    )
    --> True

Helper "lookup" (LookUp (0,[]),[])
    |> evalSubExp defaultConfig value
    |> (\err ->
        case err of
            Err (FromHelper args) ->
                args.helper == "lookup"
            _ ->
                False
    )
    --> True

Helper "invalid" (LookUp (0,[]),[])
    |> evalSubExp defaultConfig value
    |> (\err ->
        case err of
            Err (HelperNotFound _) ->
                False
            _ ->
                True
    )
    --> False