Skip to content

Commit

Permalink
Adding 'has' func to determine if an object has a named key
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
  • Loading branch information
hairyhenderson committed Mar 7, 2017
1 parent 7b6434d commit 2adb96b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Gomplate is an alternative that will let you process templates which also includ
- [Example](#example)
- [`trim`](#trim)
- [Example](#example)
- [`has`](#has)
- [Example](#example)
- [`json`](#json)
- [Example](#example)
- [`jsonArray`](#jsonarray)
Expand Down Expand Up @@ -389,6 +391,39 @@ $ FOO=" world " | gomplate < input.tmpl
Hello, world!
```

#### `has`

Has reports whether or not a given object has a property with the given key. Can be used with `if` to prevent the template from trying to access a non-existent property in an object.

##### Example

_Let's say we're using a Vault datasource..._

_`input.tmpl`:_
```go
{{ $secret := datasource "vault" "mysecret" -}}
The secret is '
{{- if (has $secret "value") }}
{{- $secret.value }}
{{- else }}
{{- $secret | toYAML }}
{{- end }}'
```

If the `secret/foo/mysecret` secret in Vault has a property named `value` set to `supersecret`:

```console
$ gomplate -d vault:///secret/foo < input.tmpl
The secret is 'supersecret'
```

On the other hand, if there is no `value` property:

```console
$ gomplate -d vault:///secret/foo < input.tmpl
The secret is 'foo: bar'
```

#### `json`

Converts a JSON string into an object. Only works for JSON Objects (not Arrays or other valid JSON types). This can be used to access properties of JSON objects.
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func NewGomplate(data *Data) *Gomplate {
funcMap: template.FuncMap{
"getenv": env.Getenv,
"bool": typeconv.Bool,
"has": typeconv.Has,
"json": typeconv.JSON,
"jsonArray": typeconv.JSONArray,
"yaml": typeconv.YAML,
Expand Down
24 changes: 24 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,27 @@ func TestSliceTemplates(t *testing.T) {
assert.Equal(t, `[foo bar 42]`, testTemplate(g, `{{slice "foo" "bar" 42}}`))
assert.Equal(t, `helloworld`, testTemplate(g, `{{range slice "hello" "world"}}{{.}}{{end}}`))
}

func TestHasTemplate(t *testing.T) {
ty := new(TypeConv)
g := &Gomplate{
funcMap: template.FuncMap{
"yaml": ty.YAML,
"has": ty.Has,
},
}
assert.Equal(t, "true", testTemplate(g, `{{has ("foo: true" | yaml) "foo"}}`))
assert.Equal(t, "false", testTemplate(g, `{{has ("foo: true" | yaml) "bar"}}`))
tmpl := `{{- $data := yaml "foo: bar\nbaz: qux\n" }}
{{- if (has $data "baz") }}
{{- $data.baz }}
{{- end }}`
assert.Equal(t, "qux", testTemplate(g, tmpl))
tmpl = `{{- $data := yaml "foo: bar\nbaz: qux\n" }}
{{- if (has $data "quux") }}
{{- $data.quux }}
{{- else }}
{{- $data.foo }}
{{- end }}`
assert.Equal(t, "bar", testTemplate(g, tmpl))
}
6 changes: 6 additions & 0 deletions typeconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ func (t *TypeConv) Join(a []interface{}, sep string) string {
return strings.Join(b, sep)
}

// Has determines whether or not a given object has a property with the given key
func (t *TypeConv) Has(in map[string]interface{}, key string) bool {
_, ok := in[key]
return ok
}

func toString(in interface{}) string {
if s, ok := in.(string); ok {
return s
Expand Down
11 changes: 11 additions & 0 deletions typeconv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,14 @@ func TestJoin(t *testing.T) {
// and best-effort with weird types
assert.Equal(t, "[foo],bar", ty.Join([]interface{}{[]string{"foo"}, "bar"}, ","))
}

func TestHas(t *testing.T) {
ty := new(TypeConv)

in := map[string]interface{}{
"foo": "bar",
}

assert.True(t, ty.Has(in, "foo"))
assert.False(t, ty.Has(in, "bar"))
}

0 comments on commit 2adb96b

Please sign in to comment.