diff --git a/options.go b/options.go index 1b643d3..2bc986b 100644 --- a/options.go +++ b/options.go @@ -12,18 +12,27 @@ type Options map[string]interface{} func (o Options) String() string { var out = make([]string, 0, len(o)) - var tmp = make([]string, 2) for k, v := range o { - tmp[0] = template.HTMLEscaper(k) - if v != nil { - tmp[1] = fmt.Sprintf("\"%s\"", template.HTMLEscaper(v)) - out = append(out, strings.Join(tmp, "=")) - } else { - // nil attribute value is interpreted as empty attribute notation - // https://www.w3.org/TR/html5/syntax.html#elements-attributes - out = append(out, tmp[0]) + if m, ok := v.(map[string]interface{}); ok { + for mk, mv := range m { + out = append(out, kv(fmt.Sprintf("%s-%s", k, mk), mv)) + } + continue } + out = append(out, kv(k, v)) } sort.Strings(out) return strings.Join(out, " ") } + +func kv(k string, v interface{}) string { + var tmp = make([]string, 2) + tmp[0] = template.HTMLEscaper(k) + if v != nil { + tmp[1] = fmt.Sprintf("\"%s\"", template.HTMLEscaper(v)) + return strings.Join(tmp, "=") + } + // nil attribute value is interpreted as empty attribute notation + // https://www.w3.org/TR/html5/syntax.html#elements-attributes + return tmp[0] +} diff --git a/options_test.go b/options_test.go index 40d06f9..05046ed 100644 --- a/options_test.go +++ b/options_test.go @@ -36,3 +36,18 @@ func Test_Options_String_Empty_Attribute(t *testing.T) { s := o.String() r.Equal(`checked value="Mark"`, s) } + +func Test_Options_Data_Map(t *testing.T) { + r := require.New(t) + o := tags.Options{ + "value": "Mark", + "id": "foo-bar", + "class": "foo bar baz", + "data": map[string]interface{}{ + "remote": true, + "method": "PUT", + }, + } + s := o.String() + r.Equal(`class="foo bar baz" data-method="PUT" data-remote="true" id="foo-bar" value="Mark"`, s) +}