summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2016-09-21 03:44:24 -0700
committerSteve Manuel <nilslice@gmail.com>2016-09-21 03:44:24 -0700
commitf3c68b123f426cb83955a78593ce7cc5b346128c (patch)
tree41ea67c1959451f4f507fd7f3a019f4658c4412b
parent2c84dd21f24fe68ccd0b0cfcb0d7cb683701ef8b (diff)
added admin interface and overview of content and types. more code reorganization.
-rw-r--r--content/post.go3
-rw-r--r--management/editor/editor.go1
-rw-r--r--management/manager/manager.go14
-rw-r--r--system/admin.go2
-rw-r--r--system/admin/admin.go51
-rw-r--r--system/db/query.go17
-rw-r--r--system/server.go42
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()