diff --git a/templatefunc.go b/templatefunc.go index 84624d2e..3d42321b 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -368,37 +368,11 @@ func RenderForm(obj interface{}) template.HTML { } fieldT := objT.Field(i) - tags := strings.Split(fieldT.Tag.Get("form"), ",") - label := fieldT.Name + ": " - name := fieldT.Name - fType := "text" - switch len(tags) { - case 1: - if tags[0] == "-" { - continue - } - if len(tags[0]) > 0 { - name = tags[0] - } - case 2: - if len(tags[0]) > 0 { - name = tags[0] - } - if len(tags[1]) > 0 { - fType = tags[1] - } - case 3: - if len(tags[0]) > 0 { - name = tags[0] - } - if len(tags[1]) > 0 { - fType = tags[1] - } - if len(tags[2]) > 0 { - label = tags[2] - } - } + label, name, fType, ignored := parseFormTag(fieldT) + if ignored { + continue + } raw = append(raw, fmt.Sprintf(`%v`, label, name, fType, fieldV.Interface())) @@ -406,6 +380,44 @@ func RenderForm(obj interface{}) template.HTML { return template.HTML(strings.Join(raw, "
")) } +// parseFormTag takes the stuct-tag of a StructField and parses the `form` value. +// returned are the form label, name-property, type and wether the field should be ignored. +func parseFormTag(fieldT reflect.StructField) (label, name, fType string, ignored bool) { + tags := strings.Split(fieldT.Tag.Get("form"), ",") + label = fieldT.Name + ": " + name = fieldT.Name + fType = "text" + ignored = false; + + switch len(tags) { + case 1: + if tags[0] == "-" { + ignored = true + } + if len(tags[0]) > 0 { + name = tags[0] + } + case 2: + if len(tags[0]) > 0 { + name = tags[0] + } + if len(tags[1]) > 0 { + fType = tags[1] + } + case 3: + if len(tags[0]) > 0 { + name = tags[0] + } + if len(tags[1]) > 0 { + fType = tags[1] + } + if len(tags[2]) > 0 { + label = tags[2] + } + } + return +} + func isStructPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct } diff --git a/templatefunc_test.go b/templatefunc_test.go index c3879fbb..a19d9bc5 100644 --- a/templatefunc_test.go +++ b/templatefunc_test.go @@ -15,6 +15,7 @@ import ( "net/url" "testing" "time" + "reflect" ) func TestSubstr(t *testing.T) { @@ -164,3 +165,41 @@ func TestRenderForm(t *testing.T) { t.Errorf("output should equal `%v` but got `%v`", result, output) } } + +func TestParseFormTag(t *testing.T) { + // create struct to contain field with different types of struct-tag `form` + type user struct { + All int `form:"name,text,年龄:"` + NoName int `form:",hidden,年龄:"` + OnlyLabel int `form:",,年龄:"` + OnlyName int `form:"name"` + Ignored int `form:"-"` + } + + objT := reflect.TypeOf(&user{}).Elem() + + label, name, fType, ignored := parseFormTag(objT.Field(0)) + if !(name == "name" && label == "年龄:" && fType == "text" && ignored == false) { + t.Errorf("Form Tag with name, label and type was not correctly parsed.") + } + + label, name, fType, ignored = parseFormTag(objT.Field(1)) + if !(name == "NoName" && label == "年龄:" && fType == "hidden" && ignored == false) { + t.Errorf("Form Tag with label and type but without name was not correctly parsed.") + } + + label, name, fType, ignored = parseFormTag(objT.Field(2)) + if !(name == "OnlyLabel" && label == "年龄:" && fType == "text" && ignored == false) { + t.Errorf("Form Tag containing only label was not correctly parsed.") + } + + label, name, fType, ignored = parseFormTag(objT.Field(3)) + if !(name == "name" && label == "OnlyName: " && fType == "text" && ignored == false) { + t.Errorf("Form Tag containing only name was not correctly parsed.") + } + + label, name, fType, ignored = parseFormTag(objT.Field(4)) + if (ignored == false) { + t.Errorf("Form Tag that should be ignored was not correctly parsed.") + } +}