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  }