From 1bc93021e3dca6405628f6fdd2dc32cff9c9836c Mon Sep 17 00:00:00 2001 From: Cameron Moore Date: Sat, 21 Mar 2020 10:15:12 -0500 Subject: [PATCH] tpl: Extend Jsonify to support optional indent parameter Fixes #5040 --- tpl/encoding/encoding.go | 30 +++++++++++++++++++++++++++--- tpl/encoding/encoding_test.go | 15 ++++++++++----- tpl/encoding/init.go | 2 +- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/tpl/encoding/encoding.go b/tpl/encoding/encoding.go index 9045acd1c..48699b52d 100644 --- a/tpl/encoding/encoding.go +++ b/tpl/encoding/encoding.go @@ -17,6 +17,7 @@ package encoding import ( "encoding/base64" "encoding/json" + "errors" "html/template" "github.com/spf13/cast" @@ -51,9 +52,32 @@ func (ns *Namespace) Base64Encode(content interface{}) (string, error) { return base64.StdEncoding.EncodeToString([]byte(conv)), nil } -// Jsonify encodes a given object to JSON. -func (ns *Namespace) Jsonify(v interface{}) (template.HTML, error) { - b, err := json.Marshal(v) +// Jsonify encodes a given object to JSON. To pretty print the JSON, pass an +// optional first argument of the indent string, such as " ". +func (ns *Namespace) Jsonify(args ...interface{}) (template.HTML, error) { + var ( + b []byte + err error + ) + + switch len(args) { + case 0: + return "", nil + case 1: + b, err = json.Marshal(args[0]) + case 2: + var indent string + + indent, err = cast.ToStringE(args[0]) + if err != nil { + break + } + + b, err = json.MarshalIndent(args[1], "", indent) + default: + err = errors.New("too many arguments to jsonify") + } + if err != nil { return "", err } diff --git a/tpl/encoding/encoding_test.go b/tpl/encoding/encoding_test.go index 2c1804dad..2f0988ff3 100644 --- a/tpl/encoding/encoding_test.go +++ b/tpl/encoding/encoding_test.go @@ -83,17 +83,22 @@ func TestJsonify(t *testing.T) { ns := New() for _, test := range []struct { + indent []interface{} v interface{} expect interface{} }{ - {[]string{"a", "b"}, template.HTML(`["a","b"]`)}, - {tstNoStringer{}, template.HTML("{}")}, - {nil, template.HTML("null")}, + {nil, []string{"a", "b"}, template.HTML(`["a","b"]`)}, + {[]interface{}{" "}, []string{"a", "b"}, template.HTML("[\n \"a\",\n \"b\"\n]")}, + {nil, tstNoStringer{}, template.HTML("{}")}, + {nil, nil, template.HTML("null")}, // errors - {math.NaN(), false}, + {nil, math.NaN(), false}, + {[]interface{}{tstNoStringer{}}, []string{"a", "b"}, false}, } { - result, err := ns.Jsonify(test.v) + args := append(test.indent, test.v) + + result, err := ns.Jsonify(args...) if b, ok := test.expect.(bool); ok && !b { c.Assert(err, qt.Not(qt.IsNil)) diff --git a/tpl/encoding/init.go b/tpl/encoding/init.go index bad1804de..8ec9f1a58 100644 --- a/tpl/encoding/init.go +++ b/tpl/encoding/init.go @@ -48,11 +48,11 @@ func init() { []string{"jsonify"}, [][2]string{ {`{{ (slice "A" "B" "C") | jsonify }}`, `["A","B","C"]`}, + {`{{ (slice "A" "B" "C") | jsonify " "}}`, "[\n \"A\",\n \"B\",\n \"C\"\n]"}, }, ) return ns - } internal.AddTemplateFuncsNamespace(f)