...

Source file src/github.com/noirbizarre/gonja/exec/macro.go

Documentation: github.com/noirbizarre/gonja/exec

     1  package exec
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/noirbizarre/gonja/nodes"
     7  	"github.com/pkg/errors"
     8  	// "github.com/noirbizarre/gonja/nodes"
     9  )
    10  
    11  // FilterFunction is the type filter functions must fulfil
    12  type Macro func(params *VarArgs) *Value
    13  
    14  type MacroSet map[string]Macro
    15  
    16  // Exists returns true if the given filter is already registered
    17  func (ms MacroSet) Exists(name string) bool {
    18  	_, existing := ms[name]
    19  	return existing
    20  }
    21  
    22  // Register registers a new filter. If there's already a filter with the same
    23  // name, Register will panic. You usually want to call this
    24  // function in the filter's init() function:
    25  // http://golang.org/doc/effective_go.html#init
    26  //
    27  // See http://www.florian-schlachter.de/post/gonja/ for more about
    28  // writing filters and tags.
    29  func (ms *MacroSet) Register(name string, fn Macro) error {
    30  	if ms.Exists(name) {
    31  		return errors.Errorf("filter with name '%s' is already registered", name)
    32  	}
    33  	(*ms)[name] = fn
    34  	return nil
    35  }
    36  
    37  // Replace replaces an already registered filter with a new implementation. Use this
    38  // function with caution since it allows you to change existing filter behaviour.
    39  func (ms *MacroSet) Replace(name string, fn Macro) error {
    40  	if !ms.Exists(name) {
    41  		return errors.Errorf("filter with name '%s' does not exist (therefore cannot be overridden)", name)
    42  	}
    43  	(*ms)[name] = fn
    44  	return nil
    45  }
    46  
    47  func MacroNodeToFunc(node *nodes.Macro, r *Renderer) (Macro, error) {
    48  	// Compute default values once
    49  	defaultKwargs := []*KwArg{}
    50  	var err error
    51  	for _, pair := range node.Kwargs {
    52  		key := r.Eval(pair.Key).String()
    53  		value := r.Eval(pair.Value)
    54  		if value.IsError() {
    55  			return nil, errors.Wrapf(value, `Unable to evaluate parameter %s=%s`, key, pair.Value)
    56  		}
    57  		defaultKwargs = append(defaultKwargs, &KwArg{key, value.Interface()})
    58  	}
    59  
    60  	return func(params *VarArgs) *Value {
    61  		var out strings.Builder
    62  		sub := r.Inherit()
    63  		sub.Out = &out
    64  
    65  		if err != nil {
    66  			return AsValue(err)
    67  		}
    68  		p := params.Expect(len(node.Args), defaultKwargs)
    69  		if p.IsError() {
    70  			return AsValue(errors.Wrapf(p, `Wrong '%s' macro signature`, node.Name))
    71  		}
    72  		for idx, arg := range p.Args {
    73  			sub.Ctx.Set(node.Args[idx], arg)
    74  		}
    75  		for key, value := range p.KwArgs {
    76  			sub.Ctx.Set(key, value)
    77  		}
    78  		err := sub.ExecuteWrapper(node.Wrapper)
    79  		if err != nil {
    80  			return AsValue(errors.Wrapf(err, `Unable to execute macro '%s`, node.Name))
    81  		}
    82  		return AsSafeValue(out.String())
    83  	}, err
    84  }
    85  

View as plain text