v2 #43
|
@ -10,7 +10,7 @@ type ImageEntry struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageEntryMetaData struct {
|
type ImageEntryMetaData struct {
|
||||||
ImagePath string `owl:"type=upload"`
|
ImagePath string `owl:"inputType=file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ImageEntry) ID() string {
|
func (e *ImageEntry) ID() string {
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package editor_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"owl-blogs/domain/model"
|
||||||
|
"owl-blogs/web/editor"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockEntryMetaData struct {
|
||||||
|
Image string `owl:"inputType=file"`
|
||||||
|
Content string `owl:"inputType=text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockEntry struct {
|
||||||
|
id string
|
||||||
|
content model.EntryContent
|
||||||
|
publishedAt *time.Time
|
||||||
|
metaData *MockEntryMetaData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MockEntry) ID() string {
|
||||||
|
return e.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MockEntry) Content() model.EntryContent {
|
||||||
|
return e.content
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MockEntry) PublishedAt() *time.Time {
|
||||||
|
return e.publishedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MockEntry) MetaData() interface{} {
|
||||||
|
return e.metaData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MockEntry) Create(id string, content string, publishedAt *time.Time, metaData model.EntryMetaData) error {
|
||||||
|
e.id = id
|
||||||
|
e.content = model.EntryContent(content)
|
||||||
|
e.publishedAt = publishedAt
|
||||||
|
e.metaData = metaData.(*MockEntryMetaData)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFieldToFormField(t *testing.T) {
|
||||||
|
field := reflect.TypeOf(&MockEntryMetaData{}).Elem().Field(0)
|
||||||
|
formField, err := editor.FieldToFormField(field)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "Image", formField.Name)
|
||||||
|
require.Equal(t, "file", formField.Params.InputType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStructToFields(t *testing.T) {
|
||||||
|
fields, err := editor.StructToFormFields(&MockEntryMetaData{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, fields, 2)
|
||||||
|
require.Equal(t, "Image", fields[0].Name)
|
||||||
|
require.Equal(t, "file", fields[0].Params.InputType)
|
||||||
|
require.Equal(t, "Content", fields[1].Name)
|
||||||
|
require.Equal(t, "text", fields[1].Params.InputType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEditorEntryForm_HtmlForm(t *testing.T) {
|
||||||
|
formService := editor.NewEditorFormService(&MockEntry{})
|
||||||
|
form, err := formService.HtmlForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Contains(t, form, "<form")
|
||||||
|
require.Contains(t, form, "method=\"POST\"")
|
||||||
|
require.Contains(t, form, "<input type=\"file\" name=\"Image\" />")
|
||||||
|
require.Contains(t, form, "<input type=\"text\" name=\"Content\" />")
|
||||||
|
require.Contains(t, form, "<input type=\"submit\" value=\"Submit\" />")
|
||||||
|
|
||||||
|
}
|
|
@ -11,9 +11,13 @@ type EditorEntryForm struct {
|
||||||
entry model.Entry
|
entry model.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EntryFormFieldParams struct {
|
||||||
|
InputType string
|
||||||
|
}
|
||||||
|
|
||||||
type EntryFormField struct {
|
type EntryFormField struct {
|
||||||
Name string
|
Name string
|
||||||
Params map[string]string
|
Params EntryFormFieldParams
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEditorFormService(entry model.Entry) *EditorEntryForm {
|
func NewEditorFormService(entry model.Entry) *EditorEntryForm {
|
||||||
|
@ -22,28 +26,66 @@ func NewEditorFormService(entry model.Entry) *EditorEntryForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EditorEntryForm) HtmlForm() string {
|
func (s *EntryFormFieldParams) ApplyTag(tagKey string, tagValue string) error {
|
||||||
meta := s.entry.MetaData()
|
switch tagKey {
|
||||||
|
case "inputType":
|
||||||
|
s.InputType = tagValue
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown tag key: %v", tagKey)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *EntryFormField) Html() string {
|
||||||
|
return fmt.Sprintf("<input type=\"%v\" name=\"%v\" />\n", s.Params.InputType, s.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FieldToFormField(field reflect.StructField) (EntryFormField, error) {
|
||||||
|
formField := EntryFormField{
|
||||||
|
Name: field.Name,
|
||||||
|
Params: EntryFormFieldParams{},
|
||||||
|
}
|
||||||
|
tag := field.Tag.Get("owl")
|
||||||
|
for _, param := range strings.Split(tag, " ") {
|
||||||
|
parts := strings.Split(param, "=")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err := formField.Params.ApplyTag(parts[0], parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return EntryFormField{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formField, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StructToFormFields(meta interface{}) ([]EntryFormField, error) {
|
||||||
entryType := reflect.TypeOf(meta).Elem()
|
entryType := reflect.TypeOf(meta).Elem()
|
||||||
numFields := entryType.NumField()
|
numFields := entryType.NumField()
|
||||||
|
|
||||||
fields := []EntryFormField{}
|
fields := []EntryFormField{}
|
||||||
for i := 0; i < numFields; i++ {
|
for i := 0; i < numFields; i++ {
|
||||||
field := EntryFormField{
|
field, err := FieldToFormField(entryType.Field(i))
|
||||||
Name: entryType.Field(i).Name,
|
if err != nil {
|
||||||
Params: map[string]string{},
|
return nil, err
|
||||||
}
|
|
||||||
tag := entryType.Field(i).Tag.Get("owl")
|
|
||||||
for _, param := range strings.Split(tag, " ") {
|
|
||||||
parts := strings.Split(param, "=")
|
|
||||||
if len(parts) == 2 {
|
|
||||||
field.Params[parts[0]] = parts[1]
|
|
||||||
} else {
|
|
||||||
field.Params[param] = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fields = append(fields, field)
|
fields = append(fields, field)
|
||||||
}
|
}
|
||||||
|
return fields, nil
|
||||||
return fmt.Sprintf("%v", fields)
|
}
|
||||||
|
|
||||||
|
func (s *EditorEntryForm) HtmlForm() (string, error) {
|
||||||
|
meta := s.entry.MetaData()
|
||||||
|
fields, err := StructToFormFields(meta)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
html := "<form method=\"POST\">\n"
|
||||||
|
for _, field := range fields {
|
||||||
|
html += field.Html()
|
||||||
|
}
|
||||||
|
html += "<input type=\"submit\" value=\"Submit\" />\n"
|
||||||
|
html += "</form>\n"
|
||||||
|
|
||||||
|
return html, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,13 @@ func NewEditorHandler(entryService *app.EntryService) *EditorHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *EditorHandler) HandleGet(c *fiber.Ctx) error {
|
func (h *EditorHandler) HandleGet(c *fiber.Ctx) error {
|
||||||
form := editor.NewEditorFormService(&model.ImageEntry{})
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
return c.SendString(form.HtmlForm())
|
formService := editor.NewEditorFormService(&model.ImageEntry{})
|
||||||
|
form, _ := formService.HtmlForm()
|
||||||
|
return c.SendString(form)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
|
func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
|
||||||
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
return c.SendString("Hello, Editor!")
|
return c.SendString("Hello, Editor!")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue