diff options
author | Steve Manuel <nilslice@gmail.com> | 2016-11-03 00:54:13 -0700 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2016-11-03 00:54:13 -0700 |
commit | 9db0046fadcd703d9903c7abd4159ded0730bf3a (patch) | |
tree | 0ac3592b120e175372e3d78276d2cbf8bbf2bccd | |
parent | 607f29fd3e61df0b921178995eb12fdee5049f16 (diff) |
simplifying Editable interface by adding Sluggable and Identifiable interfaces, moving relevant interface methods to be implemented by other types and updating caller code to assert the new interface types as needed
-rw-r--r-- | cmd/ponzu/options.go | 26 | ||||
-rw-r--r-- | content/item.go | 25 | ||||
-rw-r--r-- | content/post.go | 15 | ||||
-rw-r--r-- | management/editor/editor.go | 5 | ||||
-rw-r--r-- | management/manager/manager.go | 9 | ||||
-rw-r--r-- | system/admin/config/config.go | 9 | ||||
-rw-r--r-- | system/admin/handlers.go | 20 | ||||
-rw-r--r-- | system/db/content.go | 2 |
8 files changed, 58 insertions, 53 deletions
diff --git a/cmd/ponzu/options.go b/cmd/ponzu/options.go index 062975b..244a759 100644 --- a/cmd/ponzu/options.go +++ b/cmd/ponzu/options.go @@ -80,13 +80,14 @@ type {{ .name }} struct { Theme string ` + "`json:" + `"theme"` + "`" + ` } -// MarshalEditor writes a buffer of html to edit a {{ .name }} and partially implements editor.Editable +// MarshalEditor writes a buffer of html to edit a {{ .name }} +// partially implements editor.Editable func ({{ .initial }} *{{ .name }}) MarshalEditor() ([]byte, error) { view, err := editor.Form({{ .initial }}, editor.Field{ - // Take careful note that the first argument to these Input-like methods - // is the string version of each {{ .name }} struct tag, and must follow this pattern - // for auto-decoding and -encoding reasons. + // Take note that the first argument to these Input-like methods + // is the string version of each {{ .name }} field, and must follow + // this pattern for auto-decoding and auto-encoding reasons. View: editor.Input("Title", {{ .initial }}, map[string]string{ "label": "{{ .name }} Title", "type": "text", @@ -138,19 +139,12 @@ func init() { Types["{{ .name }}"] = func() interface{} { return new({{ .name }}) } } -// SetContentID partially implements editor.Editable -func ({{ .initial }} *{{ .name }}) SetContentID(id int) { {{ .initial }}.ID = id } - -// ContentID partially implements editor.Editable -func ({{ .initial }} *{{ .name }}) ContentID() int { return {{ .initial }}.ID } - -// ContentName partially implements editor.Editable +// ContentName is required to set the display name for a piece of content in the editor +// Partially implements editor.Editable func ({{ .initial }} *{{ .name }}) ContentName() string { return {{ .initial }}.Title } -// SetSlug partially implements editor.Editable -func ({{ .initial }} *{{ .name }}) SetSlug(slug string) { {{ .initial }}.Slug = slug } - -// Editor partially implements editor.Editable +// Editor is a buffer of bytes for the Form function to write input views +// partially implements editor.Editable func ({{ .initial }} *{{ .name }}) Editor() *editor.Editor { return &{{ .initial }}.editor } ` @@ -163,8 +157,6 @@ func newProjectInDir(path string) error { // check if anything exists at the path, ask if it should be overwritten if _, err := os.Stat(path); !os.IsNotExist(err) { fmt.Println("Path exists, overwrite contents? (y/N):") - // input := bufio.NewReader(os.Stdin) - // answer, err := input.ReadString('\n') var answer string _, err := fmt.Scanf("%s\n", &answer) diff --git a/content/item.go b/content/item.go index f4a5489..0077dc6 100644 --- a/content/item.go +++ b/content/item.go @@ -18,7 +18,28 @@ func (i Item) Touch() int64 { return i.Updated } -// ContentID partially implements the Sortable interface -func (i Item) ContentID() int { +// ItemID partially implements the Sortable interface +func (i Item) ItemID() int { return i.ID } + +// SetSlug sets the item's slug for its URL +func (i *Item) SetSlug(slug string) { + i.Slug = slug +} + +// Sluggable makes a struct locatable by URL with it's own path +// As an Item implementing Sluggable, slugs may overlap. If this is an issue, +// make your content struct (or one which imbeds Item) implement Sluggable +// and it will override the slug created by Item's SetSlug with your struct's +type Sluggable interface { + SetSlug(string) +} + +// Identifiable enables a struct to have its ID set. Typically this is done +// to set an ID to -1 indicating it is new for DB inserts, since by default +// a newly initialized struct would have an ID of 0, the int zero-value, and +// BoltDB's starting key per bucket is 0, thus overwriting the first record. +type Identifiable interface { + SetContentID(int) +} diff --git a/content/post.go b/content/post.go index dcdfeff..b81bb5a 100644 --- a/content/post.go +++ b/content/post.go @@ -74,17 +74,10 @@ func init() { Types["Post"] = func() interface{} { return new(Post) } } -// SetContentID partially implements editor.Editable -func (p *Post) SetContentID(id int) { p.ID = id } - -// ContentID partially implements editor.Editable -func (p *Post) ContentID() int { return p.ID } - -// ContentName partially implements editor.Editable +// ContentName is required to set the display name for a piece of content in the editor +// Partially implements editor.Editable func (p *Post) ContentName() string { return p.Title } -// SetSlug partially implements editor.Editable -func (p *Post) SetSlug(slug string) { p.Slug = slug } - -// Editor partially implements editor.Editable +// Editor is a buffer of bytes for the Form function to write input views +// partially implements editor.Editable func (p *Post) Editor() *editor.Editor { return &p.editor } diff --git a/management/editor/editor.go b/management/editor/editor.go index 2cfe1ea..f76197a 100644 --- a/management/editor/editor.go +++ b/management/editor/editor.go @@ -8,10 +8,7 @@ import ( // Editable ensures data is editable type Editable interface { - SetContentID(id int) - ContentID() int ContentName() string - SetSlug(slug string) Editor() *Editor MarshalEditor() ([]byte, error) } @@ -20,7 +17,7 @@ type Editable interface { type Sortable interface { Time() int64 Touch() int64 - ContentID() int + ItemID() int } // Editor is a view containing fields to manage content diff --git a/management/manager/manager.go b/management/manager/manager.go index c0c5519..2830ba4 100644 --- a/management/manager/manager.go +++ b/management/manager/manager.go @@ -112,11 +112,16 @@ type manager struct { func Manage(e editor.Editable, typeName string) ([]byte, error) { v, err := e.MarshalEditor() if err != nil { - return nil, fmt.Errorf("Couldn't marshal editor for content %T. %s", e, err.Error()) + return nil, fmt.Errorf("Couldn't marshal editor for content %s. %s", typeName, err.Error()) + } + + s, ok := e.(editor.Sortable) + if !ok { + return nil, fmt.Errorf("Content type %s does not implement content.Identifiable.", typeName) } m := manager{ - ID: e.ContentID(), + ID: s.ItemID(), Kind: typeName, Editor: template.HTML(v), } diff --git a/system/admin/config/config.go b/system/admin/config/config.go index 66f767d..ba8ffb3 100644 --- a/system/admin/config/config.go +++ b/system/admin/config/config.go @@ -18,18 +18,9 @@ type Config struct { CacheInvalidate []string `json:"-"` } -// SetContentID partially implements editor.Editable -func (c *Config) SetContentID(id int) { c.ID = id } - -// ContentID partially implements editor.Editable -func (c *Config) ContentID() int { return c.ID } - // ContentName partially implements editor.Editable func (c *Config) ContentName() string { return c.Name } -// SetSlug partially implements editor.Editable -func (c *Config) SetSlug(slug string) { c.Slug = slug } - // Editor partially implements editor.Editable func (c *Config) Editor() *editor.Editor { return &c.editor } diff --git a/system/admin/handlers.go b/system/admin/handlers.go index 12750e2..18faec9 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -752,10 +752,10 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { // adminPostListItem is a helper to create the li containing a post. // p is the asserted post as an Editable, t is the Type of the post. // specifier is passed to append a name to a namespace like _pending -func adminPostListItem(p editor.Editable, t, status string) []byte { - s, ok := p.(editor.Sortable) +func adminPostListItem(e editor.Editable, typeName, status string) []byte { + s, ok := e.(editor.Sortable) if !ok { - log.Println("Content type", t, "doesn't implement editor.Sortable") + log.Println("Content type", typeName, "doesn't implement editor.Sortable") post := `<li class="col s12">Error retreiving data. Your data type doesn't implement necessary interfaces.</li>` return []byte(post) } @@ -766,7 +766,7 @@ func adminPostListItem(p editor.Editable, t, status string) []byte { updatedTime := upTime.Format("01/02/06 03:04 PM") publishTime := tsTime.Format("01/02/06") - cid := fmt.Sprintf("%d", p.ContentID()) + cid := fmt.Sprintf("%d", s.ItemID()) switch status { case "public", "": @@ -777,14 +777,14 @@ func adminPostListItem(p editor.Editable, t, status string) []byte { post := ` <li class="col s12"> - <a href="/admin/edit?type=` + t + `&status=` + strings.TrimPrefix(status, "_") + `&id=` + cid + `">` + p.ContentName() + `</a> + <a href="/admin/edit?type=` + typeName + `&status=` + strings.TrimPrefix(status, "_") + `&id=` + cid + `">` + e.ContentName() + `</a> <span class="post-detail">Updated: ` + updatedTime + `</span> <span class="publish-date right">` + publishTime + `</span> <form enctype="multipart/form-data" class="quick-delete-post __ponzu right" action="/admin/edit/delete" method="post"> <span>Delete</span> <input type="hidden" name="id" value="` + cid + `" /> - <input type="hidden" name="type" value="` + t + status + `" /> + <input type="hidden" name="type" value="` + typeName + status + `" /> </form> </li>` @@ -940,7 +940,13 @@ func editHandler(res http.ResponseWriter, req *http.Request) { return } } else { - post.(editor.Editable).SetContentID(-1) + s, ok := post.(content.Identifiable) + if !ok { + log.Println("Content type", typeName, "doesn't implement editor.Sortable") + return + } + s.SetContentID(-1) + } m, err := manager.Manage(post.(editor.Editable), t) diff --git a/system/db/content.go b/system/db/content.go index cfbd4ef..b43d611 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -381,7 +381,7 @@ func postToJSON(ns string, data url.Values) ([]byte, error) { if err != nil { return nil, err } - post.(editor.Editable).SetSlug(slug) + post.(content.Sluggable).SetSlug(slug) // marshall content struct to json for db storage j, err := json.Marshal(post) |