summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2016-09-19 02:09:29 -0700
committerSteve Manuel <nilslice@gmail.com>2016-09-19 02:09:29 -0700
commit2ed153f8d287b3ffb5e8d1667ab51c922d82c504 (patch)
tree8bde4e8865e5502ff72487252bcd5fcc09cd89c2
parentd62f31d1932125db59c4cf813c54d95a4a0200ee (diff)
reorganizing files and dir structure. adding initial (incomplete) management, types, system and db functionality.
-rw-r--r--content/post.go (renamed from post.go)50
-rw-r--r--content/types.go7
-rw-r--r--management/editor/editor.go (renamed from editor/editor.go)10
-rw-r--r--management/editor/elements.go (renamed from editor/element.go)2
-rw-r--r--management/manager/manager.go46
-rw-r--r--server.go78
-rw-r--r--system/admin.go2
-rw-r--r--system/db/item.go8
-rw-r--r--system/db/query.go21
9 files changed, 181 insertions, 43 deletions
diff --git a/post.go b/content/post.go
index 3ae0b92..65ea88f 100644
--- a/post.go
+++ b/content/post.go
@@ -1,15 +1,15 @@
-package main
+package content
import (
- "bytes"
"fmt"
- "net/http"
- "github.com/nilslice/cms/editor"
+ "github.com/nilslice/cms/management/editor"
+ "github.com/nilslice/cms/system/db"
)
// Post is the generic content struct
type Post struct {
+ db.Item
editor editor.Editor
Title []byte `json:"title"`
@@ -18,23 +18,18 @@ type Post struct {
Timestamp []byte `json:"timestamp"`
}
-// Editor partially implements editor.Editable
-func (p *Post) Editor() *editor.Editor {
- return &p.editor
+func init() {
+ Types["Post"] = Post{}
}
-// NewViewBuffer partially implements editor.Editable
-func (p *Post) NewViewBuffer() {
- p.editor.ViewBuf = &bytes.Buffer{}
-}
+// ContentID partially implements editor.Editable
+func (p Post) ContentID() int { return p.ID }
-// Render partially implements editor.Editable
-func (p *Post) Render() []byte {
- return p.editor.ViewBuf.Bytes()
-}
+// Editor partially implements editor.Editable
+func (p Post) Editor() *editor.Editor { return &p.editor }
-// EditView writes a buffer of html to edit a Post
-func (p Post) EditView() ([]byte, error) {
+// MarshalEditor writes a buffer of html to edit a Post and partially implements editor.Editable
+func (p Post) MarshalEditor() ([]byte, error) {
view, err := editor.New(&p,
editor.Field{
View: editor.Input("Title", &p, map[string]string{
@@ -70,24 +65,3 @@ func (p Post) EditView() ([]byte, error) {
return view, nil
}
-
-func (p Post) ServeHTTP(res http.ResponseWriter, req *http.Request) {
- res.Header().Set("Content-type", "text/html")
- resp, err := p.EditView()
- if err != nil {
- fmt.Println(err)
- }
- res.Write(resp)
-}
-
-func main() {
- p := Post{
- Content: []byte("<h3>H</h3>ello. My name is <em>Steve</em>."),
- Title: []byte("Profound introduction"),
- Author: []byte("Steve Manuel"),
- Timestamp: []byte("2016-09-16"),
- }
-
- http.ListenAndServe(":8080", p)
-
-}
diff --git a/content/types.go b/content/types.go
new file mode 100644
index 0000000..778f742
--- /dev/null
+++ b/content/types.go
@@ -0,0 +1,7 @@
+package content
+
+import "github.com/nilslice/cms/management/editor"
+
+// Types is a map used to reference a type name to its actual Editable type
+// mainly for lookups in /admin route based utilities
+var Types = make(map[string]editor.Editable)
diff --git a/editor/editor.go b/management/editor/editor.go
index 11dc064..24b514e 100644
--- a/editor/editor.go
+++ b/management/editor/editor.go
@@ -6,9 +6,9 @@ import "bytes"
// Editable ensures data is editable
type Editable interface {
+ ContentID() int
Editor() *Editor
- NewViewBuffer()
- Render() []byte
+ MarshalEditor() ([]byte, error)
}
// Editor is a view containing fields to manage content
@@ -25,15 +25,15 @@ type Field struct {
// New takes editable content and any number of Field funcs to describe the edit
// page for any content struct added by a user
func New(post Editable, fields ...Field) ([]byte, error) {
- post.NewViewBuffer()
-
editor := post.Editor()
+ editor.ViewBuf = &bytes.Buffer{}
+
for _, f := range fields {
addFieldToEditorView(editor, f)
}
- return post.Render(), nil
+ return editor.ViewBuf.Bytes(), nil
}
func addFieldToEditorView(e *Editor, f Field) {
diff --git a/editor/element.go b/management/editor/elements.go
index 519ce5d..59d74f0 100644
--- a/editor/element.go
+++ b/management/editor/elements.go
@@ -60,6 +60,7 @@ func domElementSelfClose(e *element, wrapInLabel bool) []byte {
for attr, value := range e.Attrs {
e.viewBuf.Write([]byte(attr + `="` + string(value) + `"`))
}
+ e.viewBuf.Write([]byte(` name="` + e.Name + `"`))
e.viewBuf.Write([]byte(` />`))
return e.viewBuf.Bytes()
@@ -75,6 +76,7 @@ func domElement(e *element, wrapInLabel bool) []byte {
for attr, value := range e.Attrs {
e.viewBuf.Write([]byte(attr + `="` + string(value) + `"`))
}
+ e.viewBuf.Write([]byte(` name="` + e.Name + `"`))
e.viewBuf.Write([]byte(` >`))
e.viewBuf.Write([]byte(e.data))
diff --git a/management/manager/manager.go b/management/manager/manager.go
new file mode 100644
index 0000000..83ed63a
--- /dev/null
+++ b/management/manager/manager.go
@@ -0,0 +1,46 @@
+package manager
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "reflect"
+
+ "github.com/nilslice/cms/management/editor"
+)
+
+var html = `
+<div class="manager">
+ <form method="post" action="/admin/edit?type={{.Kind}}&contentId={{.ID}}">
+ {{.Editor}}
+ <input type="submit" value="Save"/>
+ </form>
+</div>
+`
+
+type form struct {
+ ID int
+ Kind string
+ Editor template.HTML
+}
+
+// Manage ...
+func Manage(e editor.Editable) ([]byte, error) {
+ v, err := e.MarshalEditor()
+ if err != nil {
+ return nil, fmt.Errorf("Couldn't marshal editor for content %T. %s", e, err.Error())
+ }
+
+ f := form{
+ ID: e.ContentID(),
+ Kind: reflect.TypeOf(e).Name(),
+ Editor: template.HTML(v),
+ }
+
+ // execute html template into buffer for func return val
+ buf := &bytes.Buffer{}
+ tmpl := template.Must(template.New("manager").Parse(html))
+ tmpl.Execute(buf, f)
+
+ return buf.Bytes(), nil
+}
diff --git a/server.go b/server.go
new file mode 100644
index 0000000..d7605f6
--- /dev/null
+++ b/server.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/nilslice/cms/content"
+ "github.com/nilslice/cms/management/manager"
+)
+
+const (
+ // ErrTypeNotRegistered means content type isn't registered (not found in content.Types map)
+ ErrTypeNotRegistered = `Error:
+There is no type registered for %[1]s
+
+Add this to the file which defines %[1]s{} in the 'content' package:
+--------------------------------+
+
+func init() {
+ Types["%[1]s"] = %[1]s{}
+}
+
+--------------------------------+
+`
+)
+
+func main() {
+ // p := content.Post{
+ // Title: []byte("Profound introduction"),
+ // Content: []byte("<h3>H</h3>ello. My name is <em>Steve</em>."),
+ // Author: []byte("Steve Manuel"),
+ // Timestamp: []byte("2016-09-16"),
+ // }
+ // p.ID = 1
+
+ http.HandleFunc("/admin/edit", func(res http.ResponseWriter, req *http.Request) {
+ switch req.Method {
+ case http.MethodGet:
+ err := req.ParseForm()
+ if err != nil {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ t := req.FormValue("type")
+ contentType, ok := content.Types[t]
+ if !ok {
+ fmt.Fprintf(res, ErrTypeNotRegistered, t)
+ return
+ }
+ view, err := manager.Manage(contentType)
+ if err != nil {
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ res.Header().Set("Content-Type", "text/html")
+ res.Write(view)
+
+ case http.MethodPost:
+ err := req.ParseForm()
+ if err != nil {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ id := req.FormValue("contentId")
+ if id == "0" {
+ res.Write([]byte("This would create a new post"))
+ return
+ }
+
+ res.Write([]byte("Updated post " + id))
+ }
+ })
+
+ http.ListenAndServe(":8080", nil)
+
+}
diff --git a/system/admin.go b/system/admin.go
new file mode 100644
index 0000000..7fa156a
--- /dev/null
+++ b/system/admin.go
@@ -0,0 +1,2 @@
+// Package system exposes all interfaces to admin and api components
+package system
diff --git a/system/db/item.go b/system/db/item.go
new file mode 100644
index 0000000..23e8553
--- /dev/null
+++ b/system/db/item.go
@@ -0,0 +1,8 @@
+// Package db ...
+package db
+
+// Item should only be embedded into content type structs.
+// Helper for DB-related actions
+type Item struct {
+ ID int `json:"_id"`
+}
diff --git a/system/db/query.go b/system/db/query.go
new file mode 100644
index 0000000..c9cf37c
--- /dev/null
+++ b/system/db/query.go
@@ -0,0 +1,21 @@
+package db
+
+// Set inserts or updates values in the database.
+// The `key` argument is a string made up of namespace:id (string:int)
+func Set(key string) error {
+
+ return nil
+}
+
+// Get retrives one item from the database. Non-existent values will return an empty []byte
+// The `key` argument is a string made up of namespace:id (string:int)
+func Get(key string) []byte {
+
+ return nil
+}
+
+// GetAll retrives all items from the database within the provided namespace
+func GetAll(namespace string) [][]byte {
+
+ return nil
+}