// Package editor enables users to create edit views from their content // structs so that admins can manage content package editor import ( "bytes" ) // Editable ensures data is editable type Editable interface { ContentName() string Editor() *Editor MarshalEditor() ([]byte, error) } // Sortable ensures data is sortable by time type Sortable interface { Time() int64 Touch() int64 ItemID() int } // Editor is a view containing fields to manage content type Editor struct { ViewBuf *bytes.Buffer } // Field is used to create the editable view for a field // within a particular content struct type Field struct { View []byte } // Form takes editable content and any number of Field funcs to describe the edit // page for any content struct added by a user func Form(post Editable, fields ...Field) ([]byte, error) { editor := post.Editor() editor.ViewBuf = &bytes.Buffer{} editor.ViewBuf.Write([]byte(``)) // content items with Item embedded have some default fields we need to render editor.ViewBuf.Write([]byte(`
`)) for _, f := range fields { addFieldToEditorView(editor, f) } editor.ViewBuf.Write([]byte(`
`)) publishTime := `
:
` editor.ViewBuf.Write([]byte(publishTime)) addPostDefaultFieldsToEditorView(post, editor) submit := `
` editor.ViewBuf.Write([]byte(submit + `
`)) return editor.ViewBuf.Bytes(), nil } func addFieldToEditorView(e *Editor, f Field) { e.ViewBuf.Write(f.View) } func addPostDefaultFieldsToEditorView(p Editable, e *Editor) { defaults := []Field{ Field{ View: Input("Slug", p, map[string]string{ "label": "URL Slug", "type": "text", "disabled": "true", "placeholder": "Will be set automatically", }), }, Field{ View: Timestamp("Timestamp", p, map[string]string{ "type": "hidden", "class": "timestamp __ponzu", }), }, Field{ View: Timestamp("Updated", p, map[string]string{ "type": "hidden", "class": "updated __ponzu", }), }, } for _, f := range defaults { addFieldToEditorView(e, f) } }