summaryrefslogtreecommitdiff
path: root/examples/docker/admin/cmd/ponzu/generate.go
diff options
context:
space:
mode:
Diffstat (limited to 'examples/docker/admin/cmd/ponzu/generate.go')
-rw-r--r--examples/docker/admin/cmd/ponzu/generate.go263
1 files changed, 263 insertions, 0 deletions
diff --git a/examples/docker/admin/cmd/ponzu/generate.go b/examples/docker/admin/cmd/ponzu/generate.go
new file mode 100644
index 0000000..a4a9d2c
--- /dev/null
+++ b/examples/docker/admin/cmd/ponzu/generate.go
@@ -0,0 +1,263 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "os"
+ "path/filepath"
+ "strings"
+ "text/template"
+)
+
+type generateType struct {
+ Name string
+ Initial string
+ Fields []generateField
+}
+
+type generateField struct {
+ Name string
+ Initial string
+ TypeName string
+ JSONName string
+ View string
+}
+
+// blog title:string Author:string PostCategory:string content:string some_thing:int
+func parseType(args []string) (generateType, error) {
+ t := generateType{
+ Name: fieldName(args[0]),
+ }
+ t.Initial = strings.ToLower(string(t.Name[0]))
+
+ fields := args[1:]
+ for _, field := range fields {
+ f, err := parseField(field, t)
+ if err != nil {
+ return generateType{}, err
+ }
+ // NEW
+ // set initial (1st character of the type's name) on field so we don't need
+ // to set the template variable like was done in prior version
+ f.Initial = t.Initial
+
+ t.Fields = append(t.Fields, f)
+ }
+
+ return t, nil
+}
+
+func parseField(raw string, gt generateType) (generateField, error) {
+ // contents:string or // contents:string:richtext
+ if !strings.Contains(raw, ":") {
+ return generateField{}, fmt.Errorf("Invalid generate argument. [%s]", raw)
+ }
+
+ data := strings.Split(raw, ":")
+
+ field := generateField{
+ Name: fieldName(data[0]),
+ Initial: gt.Initial,
+ TypeName: strings.ToLower(data[1]),
+ JSONName: fieldJSONName(data[0]),
+ }
+
+ fieldType := "input"
+ if len(data) == 3 {
+ fieldType = data[2]
+ }
+
+ err := setFieldView(&field, fieldType)
+ if err != nil {
+ return generateField{}, err
+ }
+
+ return field, nil
+}
+
+// get the initial field name passed and check it for all possible cases
+// MyTitle:string myTitle:string my_title:string -> MyTitle
+// error-message:string -> ErrorMessage
+func fieldName(name string) string {
+ // remove _ or - if first character
+ if name[0] == '-' || name[0] == '_' {
+ name = name[1:]
+ }
+
+ // remove _ or - if last character
+ if name[len(name)-1] == '-' || name[len(name)-1] == '_' {
+ name = name[:len(name)-1]
+ }
+
+ // upcase the first character
+ name = strings.ToUpper(string(name[0])) + name[1:]
+
+ // remove _ or - character, and upcase the character immediately following
+ for i := 0; i < len(name); i++ {
+ r := rune(name[i])
+ if isUnderscore(r) || isHyphen(r) {
+ up := strings.ToUpper(string(name[i+1]))
+ name = name[:i] + up + name[i+2:]
+ }
+ }
+
+ return name
+}
+
+// get the initial field name passed and convert to json-like name
+// MyTitle:string myTitle:string my_title:string -> my_title
+// error-message:string -> error-message
+func fieldJSONName(name string) string {
+ // remove _ or - if first character
+ if name[0] == '-' || name[0] == '_' {
+ name = name[1:]
+ }
+
+ // downcase the first character
+ name = strings.ToLower(string(name[0])) + name[1:]
+
+ // check for uppercase character, downcase and insert _ before it if i-1
+ // isn't already _ or -
+ for i := 0; i < len(name); i++ {
+ r := rune(name[i])
+ if isUpper(r) {
+ low := strings.ToLower(string(r))
+ if name[i-1] == '_' || name[i-1] == '-' {
+ name = name[:i] + low + name[i+1:]
+ } else {
+ name = name[:i] + "_" + low + name[i+1:]
+ }
+ }
+ }
+
+ return name
+}
+
+// set the specified view inside the editor field for a generated field for a type
+func setFieldView(field *generateField, viewType string) error {
+ var err error
+ var tmpl *template.Template
+ buf := &bytes.Buffer{}
+
+ pwd, err := os.Getwd()
+ if err != nil {
+ return err
+ }
+
+ tmplDir := filepath.Join(pwd, "cmd", "ponzu", "templates")
+ tmplFrom := func(filename string) (*template.Template, error) {
+ return template.ParseFiles(filepath.Join(tmplDir, filename))
+ }
+
+ viewType = strings.ToLower(viewType)
+ switch viewType {
+ case "checkbox":
+ tmpl, err = tmplFrom("gen-checkbox.tmpl")
+ case "custom":
+ tmpl, err = tmplFrom("gen-custom.tmpl")
+ case "file":
+ tmpl, err = tmplFrom("gen-file.tmpl")
+ case "hidden":
+ tmpl, err = tmplFrom("gen-hidden.tmpl")
+ case "input", "text":
+ tmpl, err = tmplFrom("gen-input.tmpl")
+ case "richtext":
+ tmpl, err = tmplFrom("gen-richtext.tmpl")
+ case "select":
+ tmpl, err = tmplFrom("gen-select.tmpl")
+ case "textarea":
+ tmpl, err = tmplFrom("gen-textarea.tmpl")
+ case "tags":
+ tmpl, err = tmplFrom("gen-tags.tmpl")
+ default:
+ msg := fmt.Sprintf("'%s' is not a recognized view type. Using 'input' instead.", viewType)
+ fmt.Println(msg)
+ tmpl, err = tmplFrom("gen-input.tmpl")
+ }
+
+ if err != nil {
+ return err
+ }
+
+ err = tmpl.Execute(buf, field)
+ if err != nil {
+ return err
+ }
+
+ field.View = buf.String()
+
+ return nil
+}
+
+func isUpper(char rune) bool {
+ if char >= 'A' && char <= 'Z' {
+ return true
+ }
+
+ return false
+}
+
+func isUnderscore(char rune) bool {
+ return char == '_'
+}
+
+func isHyphen(char rune) bool {
+ return char == '-'
+}
+
+func generateContentType(args []string) error {
+ name := args[0]
+ fileName := strings.ToLower(name) + ".go"
+
+ // 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
+ }
+
+ // parse type info from args
+ gt, err := parseType(args)
+ if err != nil {
+ return fmt.Errorf("Failed to parse type args: %s", err.Error())
+ }
+
+ tmplPath := filepath.Join(pwd, "cmd", "ponzu", "templates", "gen-content.tmpl")
+ tmpl, err := template.ParseFiles(tmplPath)
+ if err != nil {
+ return fmt.Errorf("Failed to parse template: %s", err.Error())
+ }
+
+ buf := &bytes.Buffer{}
+ err = tmpl.Execute(buf, gt)
+ if err != nil {
+ return fmt.Errorf("Failed to execute template: %s", err.Error())
+ }
+
+ fmtBuf, err := format.Source(buf.Bytes())
+ if err != nil {
+ return fmt.Errorf("Failed to format template: %s", err.Error())
+ }
+
+ _, err = file.Write(fmtBuf)
+ if err != nil {
+ return fmt.Errorf("Failed to write generated file buffer: %s", err.Error())
+ }
+
+ return nil
+}