From eadb199f80bf30b5910b53cbec305c2c19f48c37 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Thu, 12 Jan 2017 16:10:54 -0800 Subject: moving reference addon to outside repo - no more "official" addons. Addon repo now is just links to good addons --- addons/github.com/bosssauce/reference/reference.go | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 addons/github.com/bosssauce/reference/reference.go (limited to 'addons/github.com/bosssauce/reference/reference.go') diff --git a/addons/github.com/bosssauce/reference/reference.go b/addons/github.com/bosssauce/reference/reference.go new file mode 100644 index 0000000..9918f36 --- /dev/null +++ b/addons/github.com/bosssauce/reference/reference.go @@ -0,0 +1,150 @@ +// Package reference is a Ponzu addon to enable content editors to create +// references to other content types which are stored as query strings within +// the referencer's content DB +package reference + +import ( + "bytes" + "encoding/json" + "fmt" + "html/template" + "log" + "strings" + + "github.com/ponzu-cms/ponzu/management/editor" + "github.com/ponzu-cms/ponzu/system/addon" +) + +// Select returns the []byte of a HTML element plus internal with a label. +// It also includes repeat controllers (+ / -) so the element can be +// dynamically multiplied or reduced. +// IMPORTANT: +// The `fieldName` argument will cause a panic if it is not exactly the string +// form of the struct field that this editor input is representing +func SelectRepeater(fieldName string, p interface{}, attrs map[string]string, contentType, tmplString string) []byte { + scope := editor.TagNameFromStructField(fieldName, p) + html := bytes.Buffer{} + _, err := html.WriteString(``) + if err != nil { + log.Println("Error writing HTML string to SelectRepeater buffer") + return nil + } + + if _, ok := attrs["class"]; ok { + attrs["class"] += " browser-default" + } else { + attrs["class"] = "browser-default" + } + + // find the field values in p to determine if an option is pre-selected + fieldVals := editor.ValueFromStructField(fieldName, p) + vals := strings.Split(fieldVals, "__ponzu") + + options, err := encodeDataToOptions(contentType, tmplString) + if err != nil { + log.Println("Error encoding data to options for", contentType, err) + return nil + } + + for _, val := range vals { + sel := editor.NewElement("select", attrs["label"], fieldName, p, attrs) + var opts []*editor.Element + + // provide a call to action for the select element + cta := &editor.Element{ + TagName: "option", + Attrs: map[string]string{"disabled": "true", "selected": "true"}, + Data: "Select an option...", + ViewBuf: &bytes.Buffer{}, + } + + // provide a selection reset (will store empty string in db) + reset := &editor.Element{ + TagName: "option", + Attrs: map[string]string{"value": ""}, + Data: "None", + ViewBuf: &bytes.Buffer{}, + } + + opts = append(opts, cta, reset) + + for k, v := range options { + optAttrs := map[string]string{"value": k} + if k == val { + optAttrs["selected"] = "true" + } + opt := &editor.Element{ + TagName: "option", + Attrs: optAttrs, + Data: v, + ViewBuf: &bytes.Buffer{}, + } + + opts = append(opts, opt) + } + + _, err := html.Write(editor.DOMElementWithChildrenSelect(sel, opts)) + if err != nil { + log.Println("Error writing DOMElementWithChildrenSelect to SelectRepeater buffer") + return nil + } + } + + _, err = html.WriteString("") + if err != nil { + log.Println("Error writing HTML string to SelectRepeater buffer") + return nil + } + + return append(html.Bytes(), editor.RepeatController(fieldName, p, "select", ".input-field")...) +} + +func encodeDataToOptions(contentType, tmplString string) (map[string]string, error) { + // encode all content type from db into options map + // options in form of map["?type=&id="]t.String() + options := make(map[string]string) + + var all map[string]interface{} + j := addon.ContentAll(contentType) + + err := json.Unmarshal(j, &all) + if err != nil { + return nil, err + } + + // make template for option html display + tmpl := template.Must(template.New(contentType).Parse(tmplString)) + + // make data something usable to iterate over and assign options + data := all["data"].([]interface{}) + + for i := range data { + item := data[i].(map[string]interface{}) + k := fmt.Sprintf("?type=%s&id=%.0f", contentType, item["id"].(float64)) + v := &bytes.Buffer{} + err := tmpl.Execute(v, item) + if err != nil { + return nil, fmt.Errorf( + "Error executing template for reference of %s: %s", + contentType, err.Error()) + } + + options[k] = v.String() + } + + return options, nil +} -- cgit v1.2.3