summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2017-05-07 20:07:09 -0700
committerSteve Manuel <nilslice@gmail.com>2017-05-07 20:07:09 -0700
commitdba96b5b097e87ce1ac4d061667fcd68bfc4beab (patch)
tree69d14ca08f85042ae1f41dfbf755038c666e59b9
parentbf9bc29974c11ff2a636692952446b524dd5b643 (diff)
adding reference type and auto-repeater generate syntax to the CLI, updating templates to support
-rw-r--r--cmd/ponzu/generate.go157
-rw-r--r--cmd/ponzu/templates/gen-content.tmpl4
-rw-r--r--cmd/ponzu/templates/gen-file-repeater.tmpl4
-rw-r--r--cmd/ponzu/templates/gen-input-repeater.tmpl5
-rw-r--r--cmd/ponzu/templates/gen-reference-repeater.tmpl6
-rw-r--r--cmd/ponzu/templates/gen-reference.tmpl6
-rw-r--r--cmd/ponzu/templates/gen-select-repeater.tmpl5
7 files changed, 163 insertions, 24 deletions
diff --git a/cmd/ponzu/generate.go b/cmd/ponzu/generate.go
index d28f0a2..5211df8 100644
--- a/cmd/ponzu/generate.go
+++ b/cmd/ponzu/generate.go
@@ -11,9 +11,10 @@ import (
)
type generateType struct {
- Name string
- Initial string
- Fields []generateField
+ Name string
+ Initial string
+ Fields []generateField
+ HasReferences bool
}
type generateField struct {
@@ -22,6 +23,10 @@ type generateField struct {
TypeName string
JSONName string
View string
+
+ IsReference bool
+ ReferenceName string
+ ReferenceJSONTags []string
}
var reservedFieldNames = map[string]string{
@@ -59,7 +64,7 @@ func parseType(args []string) (generateType, error) {
fields := args[1:]
for _, field := range fields {
- f, err := parseField(field, t)
+ f, err := parseField(field, &t)
if err != nil {
return generateType{}, err
}
@@ -88,8 +93,12 @@ func parseType(args []string) (generateType, error) {
return t, nil
}
-func parseField(raw string, gt generateType) (generateField, error) {
- // contents:string or // contents:string:richtext
+func parseField(raw string, gt *generateType) (generateField, error) {
+ // contents:string
+ // contents:string:richtext
+ // author:@author,name,age
+ // authors:[]@author,name,age
+
if !strings.Contains(raw, ":") {
return generateField{}, fmt.Errorf("Invalid generate argument. [%s]", raw)
}
@@ -99,16 +108,17 @@ func parseField(raw string, gt generateType) (generateField, error) {
field := generateField{
Name: fieldName(data[0]),
Initial: gt.Initial,
- TypeName: strings.ToLower(data[1]),
JSONName: fieldJSONName(data[0]),
}
- fieldType := "input"
+ setFieldTypeName(&field, data[1], gt)
+
+ viewType := "input"
if len(data) == 3 {
- fieldType = data[2]
+ viewType = data[2]
}
- err := setFieldView(&field, fieldType)
+ err := setFieldView(&field, viewType)
if err != nil {
return generateField{}, err
}
@@ -116,6 +126,47 @@ func parseField(raw string, gt generateType) (generateField, error) {
return field, nil
}
+// parse the field's type name and check if it is a special reference type, or
+// a slice of reference types, which we'll set their underlying type to string
+// or []string respectively
+func setFieldTypeName(field *generateField, fieldType string, gt *generateType) {
+ if !strings.Contains(fieldType, "@") {
+ // not a reference, set as-is downcased
+ field.TypeName = strings.ToLower(fieldType)
+ field.IsReference = false
+ return
+ }
+
+ // some possibilities are
+ // @author,name,age
+ // []@author,name,age
+ // -------------------
+ // [] = slice of author
+ // @author = reference to Author struct
+ // ,name,age = JSON tag names from Author struct fields to use as select option display
+
+ if strings.Contains(fieldType, ",") {
+ referenceConf := strings.Split(fieldType, ",")
+ fieldType = referenceConf[0]
+ field.ReferenceJSONTags = referenceConf[1:]
+ }
+
+ var referenceType string
+ if strings.HasPrefix(fieldType, "[]") {
+ referenceType = strings.TrimPrefix(fieldType, "[]@")
+ fieldType = "[]string"
+ } else {
+ referenceType = strings.TrimPrefix(fieldType, "@")
+ fieldType = "string"
+ }
+
+ field.TypeName = strings.ToLower(fieldType)
+ field.ReferenceName = fieldName(referenceType)
+ field.IsReference = true
+ gt.HasReferences = true
+ return
+}
+
// 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
@@ -174,6 +225,41 @@ func fieldJSONName(name string) string {
return name
}
+func optimizeFieldView(field *generateField, viewType string) string {
+ viewType = strings.ToLower(viewType)
+
+ if field.IsReference {
+ viewType = "reference"
+ }
+
+ // if we have a []T field type, automatically make the input view a repeater
+ // as long as a repeater exists for the input type
+ repeaterElements := []string{"input", "select", "file", "reference"}
+ if strings.HasPrefix(field.TypeName, "[]") {
+ for _, el := range repeaterElements {
+ // if the viewType already is declared to be a -repeater
+ // the comparison below will fail but the switch will
+ // still find the right generator template
+ // ex. authors:"[]string":select
+ // ex. authors:string:select-repeater
+ if viewType == el {
+ viewType = viewType + "-repeater"
+ }
+ }
+ } else {
+ // if the viewType is already declared as a -repeater, but
+ // the TypeName is not of []T, add the [] prefix so the user
+ // code is correct
+ // ex. authors:string:select-repeater
+ // ex. authors:@author:select-repeater
+ if strings.HasSuffix(viewType, "-repeater") {
+ field.TypeName = "[]" + field.TypeName
+ }
+ }
+
+ return viewType
+}
+
// 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
@@ -186,34 +272,59 @@ func setFieldView(field *generateField, viewType string) error {
}
tmplDir := filepath.Join(pwd, "cmd", "ponzu", "templates")
- tmplFrom := func(filename string) (*template.Template, error) {
- return template.ParseFiles(filepath.Join(tmplDir, filename))
+ tmplFromWithDelims := func(filename string, delim [2]string) (*template.Template, error) {
+ if delim[0] == "" || delim[1] == "" {
+ delim = [2]string{"{{", "}}"}
+ }
+
+ return template.New(filename).Delims(delim[0], delim[1]).ParseFiles(filepath.Join(tmplDir, filename))
}
- viewType = strings.ToLower(viewType)
+ viewType = optimizeFieldView(field, viewType)
switch viewType {
case "checkbox":
- tmpl, err = tmplFrom("gen-checkbox.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-checkbox.tmpl", [2]string{})
case "custom":
- tmpl, err = tmplFrom("gen-custom.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-custom.tmpl", [2]string{})
case "file":
- tmpl, err = tmplFrom("gen-file.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-file.tmpl", [2]string{})
case "hidden":
- tmpl, err = tmplFrom("gen-hidden.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-hidden.tmpl", [2]string{})
case "input", "text":
- tmpl, err = tmplFrom("gen-input.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-input.tmpl", [2]string{})
case "richtext":
- tmpl, err = tmplFrom("gen-richtext.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-richtext.tmpl", [2]string{})
case "select":
- tmpl, err = tmplFrom("gen-select.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-select.tmpl", [2]string{})
case "textarea":
- tmpl, err = tmplFrom("gen-textarea.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-textarea.tmpl", [2]string{})
case "tags":
- tmpl, err = tmplFrom("gen-tags.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-tags.tmpl", [2]string{})
+
+ case "input-repeater":
+ tmpl, err = tmplFromWithDelims("gen-input-repeater.tmpl", [2]string{})
+ case "select-repeater":
+ tmpl, err = tmplFromWithDelims("gen-select-repeater.tmpl", [2]string{})
+ case "file-repeater":
+ tmpl, err = tmplFromWithDelims("gen-file-repeater.tmpl", [2]string{})
+
+ // use [[ and ]] as delimeters since reference views need to generate
+ // display names containing {{ and }}
+ case "reference":
+ tmpl, err = tmplFromWithDelims("gen-reference.tmpl", [2]string{"[[", "]]"})
+ if err != nil {
+ return err
+ }
+ case "reference-repeater":
+ tmpl, err = tmplFromWithDelims("gen-reference-repeater.tmpl", [2]string{"[[", "]]"})
+ if err != nil {
+ return err
+ }
+
default:
msg := fmt.Sprintf("'%s' is not a recognized view type. Using 'input' instead.", viewType)
fmt.Println(msg)
- tmpl, err = tmplFrom("gen-input.tmpl")
+ tmpl, err = tmplFromWithDelims("gen-input.tmpl", [2]string{})
}
if err != nil {
diff --git a/cmd/ponzu/templates/gen-content.tmpl b/cmd/ponzu/templates/gen-content.tmpl
index 2d92b88..78b5123 100644
--- a/cmd/ponzu/templates/gen-content.tmpl
+++ b/cmd/ponzu/templates/gen-content.tmpl
@@ -2,7 +2,9 @@ package content
import (
"fmt"
-
+ {{ if .HasReferences }}
+ "github.com/bosssauce/reference"
+ {{ end }}
"github.com/ponzu-cms/ponzu/management/editor"
"github.com/ponzu-cms/ponzu/system/item"
)
diff --git a/cmd/ponzu/templates/gen-file-repeater.tmpl b/cmd/ponzu/templates/gen-file-repeater.tmpl
new file mode 100644
index 0000000..973e366
--- /dev/null
+++ b/cmd/ponzu/templates/gen-file-repeater.tmpl
@@ -0,0 +1,4 @@
+View: editor.FileRepeater("{{ .Name }}", {{ .Initial }}, map[string]string{
+ "label": "{{ .Name }}",
+ "placeholder": "Upload the {{ .Name }} here",
+}), \ No newline at end of file
diff --git a/cmd/ponzu/templates/gen-input-repeater.tmpl b/cmd/ponzu/templates/gen-input-repeater.tmpl
new file mode 100644
index 0000000..faf77c4
--- /dev/null
+++ b/cmd/ponzu/templates/gen-input-repeater.tmpl
@@ -0,0 +1,5 @@
+View: editor.InputRepeater("{{ .Name }}", {{ .Initial }}, map[string]string{
+ "label": "{{ .Name }}",
+ "type": "text",
+ "placeholder": "Enter the {{ .Name }} here",
+}), \ No newline at end of file
diff --git a/cmd/ponzu/templates/gen-reference-repeater.tmpl b/cmd/ponzu/templates/gen-reference-repeater.tmpl
new file mode 100644
index 0000000..f1ca7f5
--- /dev/null
+++ b/cmd/ponzu/templates/gen-reference-repeater.tmpl
@@ -0,0 +1,6 @@
+View: reference.SelectRepeater("[[ .Name ]]", [[ .Initial ]], map[string]string{
+ "label": "[[ .Name ]]",
+ },
+ "[[ .ReferenceName ]]",
+ `[[ range .ReferenceJSONTags ]]{{ .[[ . ]] }} [[ else ]][[ .ReferenceName ]]: {{ .id }}[[ end ]]`,
+),
diff --git a/cmd/ponzu/templates/gen-reference.tmpl b/cmd/ponzu/templates/gen-reference.tmpl
new file mode 100644
index 0000000..51afd6b
--- /dev/null
+++ b/cmd/ponzu/templates/gen-reference.tmpl
@@ -0,0 +1,6 @@
+View: reference.Select("[[ .Name ]]", [[ .Initial ]], map[string]string{
+ "label": "[[ .Name ]]",
+ },
+ "[[ .ReferenceName ]]",
+ `[[ range .ReferenceJSONTags ]]{{ .[[ . ]] }} [[ else ]][[ .ReferenceName ]]: {{ .id }}[[ end ]]`,
+),
diff --git a/cmd/ponzu/templates/gen-select-repeater.tmpl b/cmd/ponzu/templates/gen-select-repeater.tmpl
new file mode 100644
index 0000000..e957411
--- /dev/null
+++ b/cmd/ponzu/templates/gen-select-repeater.tmpl
@@ -0,0 +1,5 @@
+View: editor.SelectRepeater("{{ .Name }}", {{ .Initial }}, map[string]string{
+ "label": "{{ .Name }}",
+}, map[string]string{
+ // "value": "Display Name",
+}), \ No newline at end of file