github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/pkg/template/plush.go (about) 1 package template 2 3 import ( 4 "html" 5 "io" 6 "strings" 7 "sync" 8 9 "github.com/gobuffalo/plush" 10 "github.com/gobuffalo/plush/token" 11 "github.com/pkg/errors" 12 ) 13 14 type plushTemplate struct { 15 impl *plush.Template 16 } 17 18 var once sync.Once 19 20 // parsePlush parses a plush template in the source string. 21 func parsePlush(source string, delimiters Delimiters) (Template, error) { 22 once.Do(prepHelpers) 23 24 if err := token.SetTemplatingDelimiters(delimiters.Start, delimiters.End); err != nil { 25 return plushTemplate{}, err 26 } 27 28 kt, err := plush.Parse(source) 29 if err != nil { 30 return nil, err 31 } 32 return plushTemplate{impl: kt}, nil 33 } 34 35 // Render writes the result of rendering the plush template using the provided scope to the IO writer. 36 func (t plushTemplate) Render(out io.Writer, scope Scope) error { 37 result, err := t.RenderString(scope) 38 if err != nil { 39 return err 40 } 41 result = html.UnescapeString(result) 42 _, err = out.Write([]byte(result)) // Makes copy of result. 43 return err 44 } 45 46 // Render returns the result of rendering the plush template using the provided scope. 47 func (t plushTemplate) RenderString(scope Scope) (string, error) { 48 context := plush.NewContext() 49 for k, v := range scope { 50 ks, ok := k.(string) 51 if !ok { 52 return "", errors.Errorf("Internal error: Expected all scope keys to be strings, unexpected: %v", k) 53 } 54 context.Set(ks, v) 55 } 56 return t.impl.Exec(context) 57 } 58 59 func prepHelpers() { 60 // Support the following plush helpers: 61 whitelist := []string{ 62 "markdown", // Markdown 63 "len", // Len 64 "range", // Range 65 "between", // Between 66 "until", // Until 67 "inspect", // Inspect 68 } 69 helpers, _ := plush.NewHelperMap() 70 for k, v := range plush.Helpers.Helpers() { 71 if contains(whitelist, k) { 72 helpers.Helpers()[strings.Title(k)] = v 73 } 74 } 75 plush.Helpers = helpers 76 } 77 78 func contains(strs []string, str string) bool { 79 for _, s := range strs { 80 if s == str { 81 return true 82 } 83 } 84 return false 85 }