summaryrefslogtreecommitdiff
path: root/cmd/cms
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/cms')
-rw-r--r--cmd/cms/generator.go144
-rw-r--r--cmd/cms/main.go58
-rw-r--r--cmd/cms/server.go7
3 files changed, 207 insertions, 2 deletions
diff --git a/cmd/cms/generator.go b/cmd/cms/generator.go
new file mode 100644
index 0000000..5ea296c
--- /dev/null
+++ b/cmd/cms/generator.go
@@ -0,0 +1,144 @@
+package main
+
+import (
+ "fmt"
+ "html/template"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func generateContentType(name string) error {
+ fileName := strings.ToLower(name) + ".go"
+ typeName := strings.ToUpper(string(name[0])) + string(name[1:])
+
+ // contain processed name an info for template
+ data := map[string]string{
+ "name": typeName,
+ "initial": string(fileName[0]),
+ }
+
+ // open file in ./content/ dir
+ // if exists, alert user of conflict
+ pwd, err := os.Getwd()
+ if err != nil {
+ return err
+ }
+
+ contentDir := filepath.Join(pwd, "content")
+ filePath := filepath.Join(contentDir, fileName)
+
+ if _, err := os.Stat(filePath); !os.IsNotExist(err) {
+ return fmt.Errorf("Please remove '%s' before executing this command.", fileName)
+ }
+
+ // no file exists.. ok to write new one
+ file, err := os.Create(filePath)
+ defer file.Close()
+ if err != nil {
+ return err
+ }
+
+ // execute template
+ tmpl := template.Must(template.New("content").Parse(contentTypeTmpl))
+ err = tmpl.Execute(file, data)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+const contentTypeTmpl = `
+package content
+
+import (
+ "fmt"
+
+ "github.com/nilslice/cms/management/editor"
+)
+
+// {{ .name }} is the generic content struct
+type {{ .name }} struct {
+ Item
+ editor editor.Editor
+
+/*
+ // all your custom fields must have json tags!
+ Title string ` + "`json:" + `"title"` + "`" + `
+ Content string ` + "`json:" + `"content"` + "`" + `
+ Author string ` + "`json:" + `"author"` + "`" + `
+ Timestamp string ` + "`json:" + `"timestamp"` + "`" + `
+*/
+}
+
+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
+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
+func ({{ .initial }} *{{ .name }}) Editor() *editor.Editor { return &{{ .initial }}.editor }
+
+// MarshalEditor writes a buffer of html to edit a {{ .name }} and partially implements editor.Editable
+func ({{ .initial }} *{{ .name }}) MarshalEditor() ([]byte, error) {
+/* EXAMPLE CODE (from post.go, the default content type)
+ 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.
+ View: editor.Input("Slug", {{ .initial }}, map[string]string{
+ "label": "URL Path",
+ "type": "text",
+ "disabled": "true",
+ "placeholder": "Will be set automatically",
+ }),
+ },
+ editor.Field{
+ View: editor.Input("Title", {{ .initial }}, map[string]string{
+ "label": "{{ .name }} Title",
+ "type": "text",
+ "placeholder": "Enter your {{ .name }} Title here",
+ }),
+ },
+ editor.Field{
+ View: editor.Textarea("Content", {{ .initial }}, map[string]string{
+ "label": "Content",
+ "placeholder": "Add the content of your {{ .name }} here",
+ }),
+ },
+ editor.Field{
+ View: editor.Input("Author", {{ .initial }}, map[string]string{
+ "label": "Author",
+ "type": "text",
+ "placeholder": "Enter the author name here",
+ }),
+ },
+ editor.Field{
+ View: editor.Input("Timestamp", {{ .initial }}, map[string]string{
+ "label": "Publish Date",
+ "type": "date",
+ }),
+ },
+ )
+
+ if err != nil {
+ return nil, fmt.Errorf("Failed to render {{ .name }} editor view: %s", err.Error())
+ }
+
+ return view, nil
+*/
+}
+`
diff --git a/cmd/cms/main.go b/cmd/cms/main.go
new file mode 100644
index 0000000..bf779c2
--- /dev/null
+++ b/cmd/cms/main.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+)
+
+var usage = `
+$ cms <option> <params>
+
+Options:
+generate, gen, g:
+ Generate a new content type file with boilerplat code to implement
+ the editor.Editable interface. Must be given one (1) parameter of
+ the name of the type for the new content.
+
+ Example:
+ $ cms gen Review
+
+`
+
+func init() {
+ flag.Usage = func() {
+ fmt.Println(usage)
+ }
+}
+
+func main() {
+ flag.Parse()
+
+ args := flag.Args()
+ if len(args) < 1 {
+ flag.PrintDefaults()
+ os.Exit(0)
+ }
+
+ fmt.Println(args)
+ switch args[0] {
+ case "generate", "gen", "g":
+ if len(args) < 2 {
+ flag.PrintDefaults()
+ os.Exit(0)
+ }
+
+ name := args[1]
+
+ err := generateContentType(name)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ case "serve", "s":
+ serve()
+ default:
+ flag.PrintDefaults()
+ }
+}
diff --git a/cmd/cms/server.go b/cmd/cms/server.go
index d8fa224..d3037d2 100644
--- a/cmd/cms/server.go
+++ b/cmd/cms/server.go
@@ -13,7 +13,7 @@ import (
"github.com/nilslice/cms/system/db"
)
-func main() {
+func init() {
http.HandleFunc("/admin", func(res http.ResponseWriter, req *http.Request) {
adminView := admin.Admin(nil)
@@ -76,6 +76,8 @@ func main() {
res.WriteHeader(http.StatusInternalServerError)
return
}
+ } else {
+ post.(editor.Editable).SetContentID(-1)
}
m, err := manager.Manage(post.(editor.Editable), t)
@@ -113,7 +115,8 @@ func main() {
http.Redirect(res, req, desURL, http.StatusFound)
}
})
+}
+func serve() {
http.ListenAndServe(":8080", nil)
-
}