diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-12-21 13:11:08 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-12-21 15:33:02 +0100 |
commit | cd1ed563a82f8a9ebdd3109230e34e74bf5ec6eb (patch) | |
tree | d766a7d88e59d20be9380aaf3d45b799737a288e /tpl/collections | |
parent | aa2c724195ae53e698dfaa7f9bea63e5cecea391 (diff) |
tpl: Improve template funcs GoDoc
Diffstat (limited to 'tpl/collections')
-rw-r--r-- | tpl/collections/append.go | 9 | ||||
-rw-r--r-- | tpl/collections/apply.go | 10 | ||||
-rw-r--r-- | tpl/collections/collections.go | 166 | ||||
-rw-r--r-- | tpl/collections/complement.go | 16 | ||||
-rw-r--r-- | tpl/collections/index.go | 7 | ||||
-rw-r--r-- | tpl/collections/merge.go | 3 | ||||
-rw-r--r-- | tpl/collections/merge_test.go | 1 | ||||
-rw-r--r-- | tpl/collections/sort.go | 10 | ||||
-rw-r--r-- | tpl/collections/where.go | 10 |
9 files changed, 119 insertions, 113 deletions
diff --git a/tpl/collections/append.go b/tpl/collections/append.go index 752ad2fa0..0f262b6bc 100644 --- a/tpl/collections/append.go +++ b/tpl/collections/append.go @@ -19,12 +19,15 @@ import ( "github.com/gohugoio/hugo/common/collections" ) -// Append appends the arguments up to the last one to the slice in the last argument. +// Append appends args up to the last one to the slice in the last argument. // This construct allows template constructs like this: -// {{ $pages = $pages | append $p2 $p1 }} +// +// {{ $pages = $pages | append $p2 $p1 }} +// // Note that with 2 arguments where both are slices of the same type, // the first slice will be appended to the second: -// {{ $pages = $pages | append .Site.RegularPages }} +// +// {{ $pages = $pages | append .Site.RegularPages }} func (ns *Namespace) Append(args ...any) (any, error) { if len(args) < 2 { return nil, errors.New("need at least 2 arguments to append") diff --git a/tpl/collections/apply.go b/tpl/collections/apply.go index 9fd5c2d0c..74ecc5b19 100644 --- a/tpl/collections/apply.go +++ b/tpl/collections/apply.go @@ -24,9 +24,9 @@ import ( "github.com/gohugoio/hugo/tpl" ) -// Apply takes a map, array, or slice and returns a new slice with the function fname applied over it. -func (ns *Namespace) Apply(ctx context.Context, seq any, fname string, args ...any) (any, error) { - if seq == nil { +// Apply takes a map, array, or slice c and returns a new slice with the function fname applied over it. +func (ns *Namespace) Apply(ctx context.Context, c any, fname string, args ...any) (any, error) { + if c == nil { return make([]any, 0), nil } @@ -34,7 +34,7 @@ func (ns *Namespace) Apply(ctx context.Context, seq any, fname string, args ...a return nil, errors.New("can't apply myself (no turtles allowed)") } - seqv := reflect.ValueOf(seq) + seqv := reflect.ValueOf(c) seqv, isNil := indirect(seqv) if isNil { return nil, errors.New("can't iterate over a nil value") @@ -61,7 +61,7 @@ func (ns *Namespace) Apply(ctx context.Context, seq any, fname string, args ...a return r, nil default: - return nil, fmt.Errorf("can't apply over %v", seq) + return nil, fmt.Errorf("can't apply over %v", c) } } diff --git a/tpl/collections/collections.go b/tpl/collections/collections.go index 299a504f4..687669a70 100644 --- a/tpl/collections/collections.go +++ b/tpl/collections/collections.go @@ -63,45 +63,45 @@ type Namespace struct { deps *deps.Deps } -// After returns all the items after the first N in a rangeable list. -func (ns *Namespace) After(index any, seq any) (any, error) { - if index == nil || seq == nil { +// After returns all the items after the first n items in list l. +func (ns *Namespace) After(n any, l any) (any, error) { + if n == nil || l == nil { return nil, errors.New("both limit and seq must be provided") } - indexv, err := cast.ToIntE(index) + nv, err := cast.ToIntE(n) if err != nil { return nil, err } - if indexv < 0 { - return nil, errors.New("sequence bounds out of range [" + cast.ToString(indexv) + ":]") + if nv < 0 { + return nil, errors.New("sequence bounds out of range [" + cast.ToString(nv) + ":]") } - seqv := reflect.ValueOf(seq) - seqv, isNil := indirect(seqv) + lv := reflect.ValueOf(l) + lv, isNil := indirect(lv) if isNil { return nil, errors.New("can't iterate over a nil value") } - switch seqv.Kind() { + switch lv.Kind() { case reflect.Array, reflect.Slice, reflect.String: // okay default: - return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't iterate over " + reflect.ValueOf(l).Type().String()) } - if indexv >= seqv.Len() { - return seqv.Slice(0, 0).Interface(), nil + if nv >= lv.Len() { + return lv.Slice(0, 0).Interface(), nil } - return seqv.Slice(indexv, seqv.Len()).Interface(), nil + return lv.Slice(nv, lv.Len()).Interface(), nil } -// Delimit takes a given sequence and returns a delimited HTML string. +// Delimit takes a given list l and returns a string delimited by sep. // If last is passed to the function, it will be used as the final delimiter. -func (ns *Namespace) Delimit(seq, delimiter any, last ...any) (template.HTML, error) { - d, err := cast.ToStringE(delimiter) +func (ns *Namespace) Delimit(l, sep any, last ...any) (template.HTML, error) { + d, err := cast.ToStringE(sep) if err != nil { return "", err } @@ -117,32 +117,32 @@ func (ns *Namespace) Delimit(seq, delimiter any, last ...any) (template.HTML, er } } - seqv := reflect.ValueOf(seq) - seqv, isNil := indirect(seqv) + lv := reflect.ValueOf(l) + lv, isNil := indirect(lv) if isNil { return "", errors.New("can't iterate over a nil value") } var str string - switch seqv.Kind() { + switch lv.Kind() { case reflect.Map: - sortSeq, err := ns.Sort(seq) + sortSeq, err := ns.Sort(l) if err != nil { return "", err } - seqv = reflect.ValueOf(sortSeq) + lv = reflect.ValueOf(sortSeq) fallthrough case reflect.Array, reflect.Slice, reflect.String: - for i := 0; i < seqv.Len(); i++ { - val := seqv.Index(i).Interface() + for i := 0; i < lv.Len(); i++ { + val := lv.Index(i).Interface() valStr, err := cast.ToStringE(val) if err != nil { continue } switch { - case i == seqv.Len()-2 && dLast != nil: + case i == lv.Len()-2 && dLast != nil: str += valStr + *dLast - case i == seqv.Len()-1: + case i == lv.Len()-1: str += valStr default: str += valStr + d @@ -150,15 +150,14 @@ func (ns *Namespace) Delimit(seq, delimiter any, last ...any) (template.HTML, er } default: - return "", fmt.Errorf("can't iterate over %v", seq) + return "", fmt.Errorf("can't iterate over %v", l) } return template.HTML(str), nil } -// Dictionary creates a map[string]interface{} from the given parameters by -// walking the parameters and treating them as key-value pairs. The number -// of parameters must be even. +// Dictionary creates a new map from the given parameters by +// treating values as key-value pairs. The number of values must be even. // The keys can be string slices, which will create the needed nested structure. func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) { if len(values)%2 != 0 { @@ -196,10 +195,10 @@ func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) { return root, nil } -// EchoParam returns a given value if it is set; otherwise, it returns an +// EchoParam returns a the value in the collection c with key k if is set; otherwise, it returns an // empty string. -func (ns *Namespace) EchoParam(a, key any) any { - av, isNil := indirect(reflect.ValueOf(a)) +func (ns *Namespace) EchoParam(c, k any) any { + av, isNil := indirect(reflect.ValueOf(c)) if isNil { return "" } @@ -207,12 +206,12 @@ func (ns *Namespace) EchoParam(a, key any) any { var avv reflect.Value switch av.Kind() { case reflect.Array, reflect.Slice: - index, ok := key.(int) + index, ok := k.(int) if ok && av.Len() > index { avv = av.Index(index) } case reflect.Map: - kv := reflect.ValueOf(key) + kv := reflect.ValueOf(k) if kv.Type().AssignableTo(av.Type().Key()) { avv = av.MapIndex(kv) } @@ -240,9 +239,9 @@ func (ns *Namespace) EchoParam(a, key any) any { return "" } -// First returns the first N items in a rangeable list. -func (ns *Namespace) First(limit any, seq any) (any, error) { - if limit == nil || seq == nil { +// First returns the first limit items in list l. +func (ns *Namespace) First(limit any, l any) (any, error) { + if limit == nil || l == nil { return nil, errors.New("both limit and seq must be provided") } @@ -255,27 +254,27 @@ func (ns *Namespace) First(limit any, seq any) (any, error) { return nil, errors.New("sequence length must be non-negative") } - seqv := reflect.ValueOf(seq) - seqv, isNil := indirect(seqv) + lv := reflect.ValueOf(l) + lv, isNil := indirect(lv) if isNil { return nil, errors.New("can't iterate over a nil value") } - switch seqv.Kind() { + switch lv.Kind() { case reflect.Array, reflect.Slice, reflect.String: // okay default: - return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't iterate over " + reflect.ValueOf(l).Type().String()) } - if limitv > seqv.Len() { - limitv = seqv.Len() + if limitv > lv.Len() { + limitv = lv.Len() } - return seqv.Slice(0, limitv).Interface(), nil + return lv.Slice(0, limitv).Interface(), nil } -// In returns whether v is in the set l. l may be an array or slice. +// In returns whether v is in the list l. l may be an array or slice. func (ns *Namespace) In(l any, v any) (bool, error) { if l == nil || v == nil { return false, nil @@ -354,7 +353,7 @@ func (ns *Namespace) Intersect(l1, l2 any) (any, error) { } } -// Group groups a set of elements by the given key. +// Group groups a set of items by the given key. // This is currently only supported for Pages. func (ns *Namespace) Group(key any, items any) (any, error) { if key == nil { @@ -374,10 +373,10 @@ func (ns *Namespace) Group(key any, items any) (any, error) { return nil, fmt.Errorf("grouping not supported for type %T %T", items, in) } -// IsSet returns whether a given array, channel, slice, or map has a key +// IsSet returns whether a given array, channel, slice, or map in c has the given key // defined. -func (ns *Namespace) IsSet(a any, key any) (bool, error) { - av := reflect.ValueOf(a) +func (ns *Namespace) IsSet(c any, key any) (bool, error) { + av := reflect.ValueOf(c) kv := reflect.ValueOf(key) switch av.Kind() { @@ -394,15 +393,15 @@ func (ns *Namespace) IsSet(a any, key any) (bool, error) { return av.MapIndex(kv).IsValid(), nil } default: - helpers.DistinctErrorLog.Printf("WARNING: calling IsSet with unsupported type %q (%T) will always return false.\n", av.Kind(), a) + helpers.DistinctErrorLog.Printf("WARNING: calling IsSet with unsupported type %q (%T) will always return false.\n", av.Kind(), c) } return false, nil } -// Last returns the last N items in a rangeable list. -func (ns *Namespace) Last(limit any, seq any) (any, error) { - if limit == nil || seq == nil { +// Last returns the last limit items in the list l. +func (ns *Namespace) Last(limit any, l any) (any, error) { + if limit == nil || l == nil { return nil, errors.New("both limit and seq must be provided") } @@ -415,7 +414,7 @@ func (ns *Namespace) Last(limit any, seq any) (any, error) { return nil, errors.New("sequence length must be non-negative") } - seqv := reflect.ValueOf(seq) + seqv := reflect.ValueOf(l) seqv, isNil := indirect(seqv) if isNil { return nil, errors.New("can't iterate over a nil value") @@ -425,7 +424,7 @@ func (ns *Namespace) Last(limit any, seq any) (any, error) { case reflect.Array, reflect.Slice, reflect.String: // okay default: - return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't iterate over " + reflect.ValueOf(l).Type().String()) } if limitv > seqv.Len() { @@ -435,7 +434,7 @@ func (ns *Namespace) Last(limit any, seq any) (any, error) { return seqv.Slice(seqv.Len()-limitv, seqv.Len()).Interface(), nil } -// Querify encodes the given parameters in URL-encoded form ("bar=baz&foo=quux") sorted by key. +// Querify encodes the given params in URL-encoded form ("bar=baz&foo=quux") sorted by key. func (ns *Namespace) Querify(params ...any) (string, error) { qs := url.Values{} @@ -476,12 +475,12 @@ func (ns *Namespace) Querify(params ...any) (string, error) { return qs.Encode(), nil } -// Reverse creates a copy of slice and reverses it. -func (ns *Namespace) Reverse(slice any) (any, error) { - if slice == nil { +// Reverse creates a copy of the list l and reverses it. +func (ns *Namespace) Reverse(l any) (any, error) { + if l == nil { return nil, nil } - v := reflect.ValueOf(slice) + v := reflect.ValueOf(l) switch v.Kind() { case reflect.Slice: @@ -499,14 +498,15 @@ func (ns *Namespace) Reverse(slice any) (any, error) { return sliceCopy.Interface(), nil } -// Seq creates a sequence of integers. It's named and used as GNU's seq. +// Seq creates a sequence of integers from args. It's named and used as GNU's seq. // // Examples: -// 3 => 1, 2, 3 -// 1 2 4 => 1, 3 -// -3 => -1, -2, -3 -// 1 4 => 1, 2, 3, 4 -// 1 -2 => 1, 0, -1, -2 +// +// 3 => 1, 2, 3 +// 1 2 4 => 1, 3 +// -3 => -1, -2, -3 +// 1 4 => 1, 2, 3, 4 +// 1 -2 => 1, 0, -1, -2 func (ns *Namespace) Seq(args ...any) ([]int, error) { if len(args) < 1 || len(args) > 3 { return nil, errors.New("invalid number of arguments to Seq") @@ -574,31 +574,31 @@ func (ns *Namespace) Seq(args ...any) ([]int, error) { return seq, nil } -// Shuffle returns the given rangeable list in a randomised order. -func (ns *Namespace) Shuffle(seq any) (any, error) { - if seq == nil { +// Shuffle returns list l in a randomised order. +func (ns *Namespace) Shuffle(l any) (any, error) { + if l == nil { return nil, errors.New("both count and seq must be provided") } - seqv := reflect.ValueOf(seq) - seqv, isNil := indirect(seqv) + lv := reflect.ValueOf(l) + lv, isNil := indirect(lv) if isNil { return nil, errors.New("can't iterate over a nil value") } - switch seqv.Kind() { + switch lv.Kind() { case reflect.Array, reflect.Slice, reflect.String: // okay default: - return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't iterate over " + reflect.ValueOf(l).Type().String()) } - shuffled := reflect.MakeSlice(reflect.TypeOf(seq), seqv.Len(), seqv.Len()) + shuffled := reflect.MakeSlice(reflect.TypeOf(l), lv.Len(), lv.Len()) - randomIndices := rand.Perm(seqv.Len()) + randomIndices := rand.Perm(lv.Len()) for index, value := range randomIndices { - shuffled.Index(value).Set(seqv.Index(index)) + shuffled.Index(value).Set(lv.Index(index)) } return shuffled.Interface(), nil @@ -733,14 +733,14 @@ func (ns *Namespace) Union(l1, l2 any) (any, error) { } } -// Uniq takes in a slice or array and returns a slice with subsequent +// Uniq takes returns a new list with all duplicate elements in the list l removed. // duplicate elements removed. -func (ns *Namespace) Uniq(seq any) (any, error) { - if seq == nil { +func (ns *Namespace) Uniq(l any) (any, error) { + if l == nil { return make([]any, 0), nil } - v := reflect.ValueOf(seq) + v := reflect.ValueOf(l) var slice reflect.Value switch v.Kind() { @@ -750,7 +750,7 @@ func (ns *Namespace) Uniq(seq any) (any, error) { case reflect.Array: slice = reflect.MakeSlice(reflect.SliceOf(v.Type().Elem()), 0, 0) default: - return nil, fmt.Errorf("type %T not supported", seq) + return nil, fmt.Errorf("type %T not supported", l) } seen := make(map[any]bool) @@ -770,8 +770,8 @@ func (ns *Namespace) Uniq(seq any) (any, error) { } // KeyVals creates a key and values wrapper. -func (ns *Namespace) KeyVals(key any, vals ...any) (types.KeyValues, error) { - return types.KeyValues{Key: key, Values: vals}, nil +func (ns *Namespace) KeyVals(key any, values ...any) (types.KeyValues, error) { + return types.KeyValues{Key: key, Values: values}, nil } // NewScratch creates a new Scratch which can be used to store values in a diff --git a/tpl/collections/complement.go b/tpl/collections/complement.go index 723f73b0a..0cc2b5857 100644 --- a/tpl/collections/complement.go +++ b/tpl/collections/complement.go @@ -19,19 +19,21 @@ import ( "reflect" ) -// Complement gives the elements in the last element of seqs that are not in +// Complement gives the elements in the last element of ls that are not in // any of the others. -// All elements of seqs must be slices or arrays of comparable types. +// +// All elements of ls must be slices or arrays of comparable types. // // The reasoning behind this rather clumsy API is so we can do this in the templates: -// {{ $c := .Pages | complement $last4 }} -func (ns *Namespace) Complement(seqs ...any) (any, error) { - if len(seqs) < 2 { +// +// {{ $c := .Pages | complement $last4 }} +func (ns *Namespace) Complement(ls ...any) (any, error) { + if len(ls) < 2 { return nil, errors.New("complement needs at least two arguments") } - universe := seqs[len(seqs)-1] - as := seqs[:len(seqs)-1] + universe := ls[len(ls)-1] + as := ls[:len(ls)-1] aset, err := collectIdentities(as...) if err != nil { diff --git a/tpl/collections/index.go b/tpl/collections/index.go index 13dd38672..d72d3748f 100644 --- a/tpl/collections/index.go +++ b/tpl/collections/index.go @@ -27,12 +27,11 @@ import ( // arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each // indexed item must be a map, slice, or array. // -// Copied from Go stdlib src/text/template/funcs.go. -// -// We deviate from the stdlib due to https://github.com/golang/go/issues/14751. +// Adapted from Go stdlib src/text/template/funcs.go. // -// TODO(moorereason): merge upstream changes. +// We deviate from the stdlib mostly because of https://github.com/golang/go/issues/14751. func (ns *Namespace) Index(item any, args ...any) (any, error) { + // TODO(moorereason): merge upstream changes. v := reflect.ValueOf(item) if !v.IsValid() { // See issue 10489 diff --git a/tpl/collections/merge.go b/tpl/collections/merge.go index 4d408302b..c6aa50eba 100644 --- a/tpl/collections/merge.go +++ b/tpl/collections/merge.go @@ -24,8 +24,9 @@ import ( "errors" ) -// Merge creates a copy of the final parameter and merges the preceding +// Merge creates a copy of the final parameter in params and merges the preceding // parameters into it in reverse order. +// // Currently only maps are supported. Key handling is case insensitive. func (ns *Namespace) Merge(params ...any) (any, error) { if len(params) < 2 { diff --git a/tpl/collections/merge_test.go b/tpl/collections/merge_test.go index e7a383126..4dbc30741 100644 --- a/tpl/collections/merge_test.go +++ b/tpl/collections/merge_test.go @@ -141,6 +141,7 @@ func TestMerge(t *testing.T) { } { test := test + i := i t.Run(test.name, func(t *testing.T) { t.Parallel() diff --git a/tpl/collections/sort.go b/tpl/collections/sort.go index ce76a4522..9a1928b00 100644 --- a/tpl/collections/sort.go +++ b/tpl/collections/sort.go @@ -25,13 +25,13 @@ import ( "github.com/spf13/cast" ) -// Sort returns a sorted sequence. -func (ns *Namespace) Sort(seq any, args ...any) (any, error) { - if seq == nil { +// Sort returns a sorted copy of the list l. +func (ns *Namespace) Sort(l any, args ...any) (any, error) { + if l == nil { return nil, errors.New("sequence must be provided") } - seqv, isNil := indirect(reflect.ValueOf(seq)) + seqv, isNil := indirect(reflect.ValueOf(l)) if isNil { return nil, errors.New("can't iterate over a nil value") } @@ -43,7 +43,7 @@ func (ns *Namespace) Sort(seq any, args ...any) (any, error) { case reflect.Map: sliceType = reflect.SliceOf(seqv.Type().Elem()) default: - return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't sort " + reflect.ValueOf(l).Type().String()) } collator := langs.GetCollator(ns.deps.Language) diff --git a/tpl/collections/where.go b/tpl/collections/where.go index 2cf7227a0..df29baf13 100644 --- a/tpl/collections/where.go +++ b/tpl/collections/where.go @@ -23,11 +23,11 @@ import ( "github.com/gohugoio/hugo/common/maps" ) -// Where returns a filtered subset of a given data type. -func (ns *Namespace) Where(seq, key any, args ...any) (any, error) { - seqv, isNil := indirect(reflect.ValueOf(seq)) +// Where returns a filtered subset of collection c. +func (ns *Namespace) Where(c, key any, args ...any) (any, error) { + seqv, isNil := indirect(reflect.ValueOf(c)) if isNil { - return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(seq).Type().String()) + return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(c).Type().String()) } mv, op, err := parseWhereArgs(args...) @@ -47,7 +47,7 @@ func (ns *Namespace) Where(seq, key any, args ...any) (any, error) { case reflect.Map: return ns.checkWhereMap(seqv, kv, mv, path, op) default: - return nil, fmt.Errorf("can't iterate over %v", seq) + return nil, fmt.Errorf("can't iterate over %v", c) } } |