diff --git a/entry_types/recipe.go b/entry_types/recipe.go
index 20b0a87..d6c8a51 100644
--- a/entry_types/recipe.go
+++ b/entry_types/recipe.go
@@ -15,7 +15,7 @@ type RecipeMetaData struct {
Title string `owl:"inputType=text"`
Yield string `owl:"inputType=text"`
Duration string `owl:"inputType=text"`
- Ingredients []string `owl:"inputType=text widget=textarea"`
+ Ingredients []string `owl:"inputType=text widget=textlist"`
Content string `owl:"inputType=text widget=textarea"`
}
diff --git a/render/templates/entry/Recipe.tmpl b/render/templates/entry/Recipe.tmpl
new file mode 100644
index 0000000..def1d17
--- /dev/null
+++ b/render/templates/entry/Recipe.tmpl
@@ -0,0 +1,27 @@
+
+ {{ if .MetaData.Yield }}
+ Servings: {{ .MetaData.Yield }}
+ {{ if .MetaData.Duration }}, {{end}}
+
+ {{ end }}
+
+ {{ if .MetaData.Duration }}
+ Prep Time:
+ {{ end }}
+
+
+
+
Ingredients
+
+
+ {{ range $ingredient := .MetaData.Ingredients }}
+ -
+ {{ $ingredient }}
+
+ {{ end }}
+
+
+Instructions
+{{.MetaData.Content | markdown }}
diff --git a/web/forms/form.go b/web/forms/form.go
index 398a081..5eae1ba 100644
--- a/web/forms/form.go
+++ b/web/forms/form.go
@@ -32,7 +32,7 @@ type FormFieldParams struct {
type FormField struct {
Name string
- Value string
+ Value reflect.Value
Params FormFieldParams
}
@@ -55,18 +55,30 @@ func (s *FormFieldParams) ApplyTag(tagKey string, tagValue string) error {
return nil
}
+func (s *FormField) ToWidget() Widget {
+ switch s.Params.Widget {
+ case "textarea":
+ return &TextareaWidget{*s}
+ case "textlist":
+ return &TextListWidget{*s}
+ default:
+ return &TextWidget{*s}
+ }
+}
+
func (s *FormField) Html() string {
html := ""
html += fmt.Sprintf("\n", s.Name, s.Name)
- if s.Params.InputType == "text" && s.Params.Widget == "textarea" {
- html += fmt.Sprintf("\n", s.Name, s.Name, s.Value)
- } else {
+ if s.Params.InputType == "file" {
html += fmt.Sprintf("\n", s.Params.InputType, s.Name, s.Name, s.Value)
+ } else {
+ html += s.ToWidget().Html()
+ html += "\n"
}
return html
}
-func FieldToFormField(field reflect.StructField, value string) (FormField, error) {
+func FieldToFormField(field reflect.StructField, value reflect.Value) (FormField, error) {
formField := FormField{
Name: field.Name,
Value: value,
@@ -92,7 +104,10 @@ func StructToFormFields(data interface{}) ([]FormField, error) {
numFields := dataType.NumField()
fields := []FormField{}
for i := 0; i < numFields; i++ {
- field, err := FieldToFormField(dataType.Field(i), dataValue.FieldByIndex([]int{i}).String())
+ field, err := FieldToFormField(
+ dataType.Field(i),
+ dataValue.FieldByIndex([]int{i}),
+ )
if err != nil {
return nil, err
}
@@ -134,10 +149,10 @@ func (s *Form) Parse(ctx HttpFormData) (interface{}, error) {
file, err := ctx.FormFile(fieldName)
if err != nil {
// If field already has a value, we can ignore the error
- if field.Value != "" {
+ if field.Value != reflect.Zero(field.Value.Type()) {
metaField := dataVal.Elem().FieldByName(fieldName)
if metaField.IsValid() {
- metaField.SetString(field.Value)
+ metaField.SetString(field.Value.String())
}
continue
}
@@ -167,7 +182,7 @@ func (s *Form) Parse(ctx HttpFormData) (interface{}, error) {
formValue := ctx.FormValue(fieldName)
metaField := dataVal.Elem().FieldByName(fieldName)
if metaField.IsValid() {
- metaField.SetString(formValue)
+ field.ToWidget().ParseValue(formValue, metaField)
}
}
diff --git a/web/forms/widget.go b/web/forms/widget.go
new file mode 100644
index 0000000..af010e2
--- /dev/null
+++ b/web/forms/widget.go
@@ -0,0 +1,72 @@
+package forms
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+type Widget interface {
+ Html() string
+ ParseValue(value string, output reflect.Value) error
+}
+
+type TextWidget struct {
+ FormField
+}
+
+func (s *TextWidget) Html() string {
+ html := ""
+ html += fmt.Sprintf("\n", s.Name, s.Value.String())
+ return html
+}
+
+func (s *TextWidget) ParseValue(value string, output reflect.Value) error {
+ output.SetString(value)
+ return nil
+}
+
+type TextareaWidget struct {
+ FormField
+}
+
+func (s *TextareaWidget) Html() string {
+ html := ""
+ html += fmt.Sprintf("\n", s.Name, s.Value.String())
+ return html
+}
+
+func (s *TextareaWidget) ParseValue(value string, output reflect.Value) error {
+ output.SetString(value)
+ return nil
+}
+
+type TextListWidget struct {
+ FormField
+}
+
+func (s *TextListWidget) Html() string {
+ valueList := s.Value.Interface().([]string)
+ value := strings.Join(valueList, "\n")
+
+ html := ""
+ html += fmt.Sprintf("\n", s.Name, value)
+ return html
+}
+
+func (s *TextListWidget) ParseValue(value string, output reflect.Value) error {
+ list := strings.Split(value, "\n")
+ // trim entries
+ for i, item := range list {
+ list[i] = strings.TrimSpace(item)
+ }
+ // remove empty entries
+ for i := len(list) - 1; i >= 0; i-- {
+ if list[i] == "" {
+ list = append(list[:i], list[i+1:]...)
+ }
+ }
+
+ output.Set(reflect.ValueOf(list))
+ return nil
+}