diff options
-rw-r--r-- | content/post.go | 3 | ||||
-rw-r--r-- | management/editor/editor.go | 1 | ||||
-rw-r--r-- | management/manager/manager.go | 14 | ||||
-rw-r--r-- | system/admin.go | 2 | ||||
-rw-r--r-- | system/admin/admin.go | 51 | ||||
-rw-r--r-- | system/db/query.go | 17 | ||||
-rw-r--r-- | system/server.go | 42 |
7 files changed, 118 insertions, 12 deletions
diff --git a/content/post.go b/content/post.go index 7bb36f6..4690f41 100644 --- a/content/post.go +++ b/content/post.go @@ -24,6 +24,9 @@ func init() { // ContentID partially implements editor.Editable func (p *Post) ContentID() int { return p.ID } +// ContentName partially implements editor.Editable +func (p *Post) ContentName() string { return p.Title } + // Editor 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 24b514e..0acf03e 100644 --- a/management/editor/editor.go +++ b/management/editor/editor.go @@ -7,6 +7,7 @@ import "bytes" // Editable ensures data is editable type Editable interface { ContentID() int + ContentName() string Editor() *Editor MarshalEditor() ([]byte, error) } diff --git a/management/manager/manager.go b/management/manager/manager.go index 7bdebbf..690a0a5 100644 --- a/management/manager/manager.go +++ b/management/manager/manager.go @@ -8,11 +8,11 @@ import ( "github.com/nilslice/cms/management/editor" ) -var html = ` +const managerHTML = ` <a href="/admin/edit?type={{.Kind}}" class="button">New {{.Kind}}</a> -<div class="manager"> +<div class="editor"> <form method="post" action="/admin/edit"> - {{.Editor}} + {{ .Editor }} <input type="hidden" name="id" value="{{.ID}}"/> <input type="hidden" name="type" value="{{.Kind}}"/> <input type="submit" value="Save"/> @@ -20,7 +20,7 @@ var html = ` </div> ` -type form struct { +type manager struct { ID int Kind string Editor template.HTML @@ -33,7 +33,7 @@ func Manage(e editor.Editable, typeName string) ([]byte, error) { return nil, fmt.Errorf("Couldn't marshal editor for content %T. %s", e, err.Error()) } - f := form{ + m := manager{ ID: e.ContentID(), Kind: typeName, Editor: template.HTML(v), @@ -41,8 +41,8 @@ func Manage(e editor.Editable, typeName string) ([]byte, error) { // execute html template into buffer for func return val buf := &bytes.Buffer{} - tmpl := template.Must(template.New("manager").Parse(html)) - tmpl.Execute(buf, f) + tmpl := template.Must(template.New("manager").Parse(managerHTML)) + tmpl.Execute(buf, m) return buf.Bytes(), nil } diff --git a/system/admin.go b/system/admin.go deleted file mode 100644 index 7fa156a..0000000 --- a/system/admin.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package system exposes all interfaces to admin and api components -package system diff --git a/system/admin/admin.go b/system/admin/admin.go new file mode 100644 index 0000000..bbc34cf --- /dev/null +++ b/system/admin/admin.go @@ -0,0 +1,51 @@ +// Package admin desrcibes the admin view containing references to +// various managers and editors +package admin + +import ( + "bytes" + "html/template" + + "github.com/nilslice/cms/content" +) + +const adminHTML = `<!doctype html> +<html> + <head> + <title>CMS</title> + </head> + <body> + <h1><a href="/admin">CMS</a></h1> + <div class="types"> + <ul> + {{ range $t, $f := .Types }} + <li><a href="/admin/posts?type={{ $t }}">{{ $t }}</a></li> + {{ end }} + </ul> + </div> + {{ if .Subview}} + <div class="manager"> + {{ .Subview }} + </div> + {{ end }} + </body> +</html>` + +type admin struct { + Types map[string]func() interface{} + Subview template.HTML +} + +// Admin ... +func Admin(manager []byte) []byte { + a := admin{ + Types: content.Types, + Subview: template.HTML(manager), + } + + buf := &bytes.Buffer{} + tmpl := template.Must(template.New("admin").Parse(adminHTML)) + tmpl.Execute(buf, a) + + return buf.Bytes() +} diff --git a/system/db/query.go b/system/db/query.go index 06e9c62..fd526f8 100644 --- a/system/db/query.go +++ b/system/db/query.go @@ -160,6 +160,21 @@ func Get(target string) ([]byte, error) { // GetAll retrives all items from the database within the provided namespace func GetAll(namespace string) [][]byte { + var posts [][]byte + store.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(namespace)) - return nil + len := b.Stats().KeyN + posts = make([][]byte, 0, len) + + b.ForEach(func(k, v []byte) error { + posts = append(posts, v) + + return nil + }) + + return nil + }) + + return posts } diff --git a/system/server.go b/system/server.go index 3d22b1d..d8fa224 100644 --- a/system/server.go +++ b/system/server.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/json" "fmt" "net/http" @@ -8,10 +9,46 @@ import ( "github.com/nilslice/cms/content" "github.com/nilslice/cms/management/editor" "github.com/nilslice/cms/management/manager" + "github.com/nilslice/cms/system/admin" "github.com/nilslice/cms/system/db" ) func main() { + http.HandleFunc("/admin", func(res http.ResponseWriter, req *http.Request) { + adminView := admin.Admin(nil) + + res.Header().Set("Content-Type", "text/html") + res.Write(adminView) + }) + + http.HandleFunc("/admin/posts", func(res http.ResponseWriter, req *http.Request) { + q := req.URL.Query() + t := q.Get("type") + if t == "" { + res.WriteHeader(http.StatusBadRequest) + } + + posts := db.GetAll(t) + b := &bytes.Buffer{} + p := content.Types[t]().(editor.Editable) + + html := `<a href="/admin/edit?type=` + t + `" class="button">New ` + t + `</a> + <ul class="posts">` + for i := range posts { + json.Unmarshal(posts[i], &p) + post := `<li><a href="/admin/edit?type=` + + t + `&id=` + fmt.Sprintf("%d", p.ContentID()) + + `">` + p.ContentName() + `</a></li>` + b.Write([]byte(post)) + } + html = html + b.String() + + adminView := admin.Admin([]byte(html)) + + res.Header().Set("Content-Type", "text/html") + res.Write(adminView) + }) + http.HandleFunc("/admin/edit", func(res http.ResponseWriter, req *http.Request) { switch req.Method { case http.MethodGet: @@ -41,14 +78,15 @@ func main() { } } - view, err := manager.Manage(post.(editor.Editable), t) + m, err := manager.Manage(post.(editor.Editable), t) + adminView := admin.Admin(m) if err != nil { fmt.Println(err) res.WriteHeader(http.StatusInternalServerError) return } res.Header().Set("Content-Type", "text/html") - res.Write(view) + res.Write(adminView) case http.MethodPost: err := req.ParseForm() |