From e27fd4c1b80b7acb43290ac50e9f140d690cf042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 10 Sep 2018 09:48:10 +0200 Subject: tpl/collections: Add collections.Append Before this commit you would typically use `.Scratch.Add` to manually create slices in a loop. With variable overwrite in Go 1.11, we can do better. This commit adds the `append` template func. A made-up example: ```bash {{ $p1 := index .Site.RegularPages 0 }}{{ $p2 := index .Site.RegularPages 1 }} {{ $pages := slice }} {{ if true }} {{ $pages = $pages | append $p2 $p1 }} {{ end }} ``` Note that with 2 slices as arguments, the two examples below will give the same result: ```bash {{ $s1 := slice "a" "b" | append (slice "c" "d") }} {{ $s2 := slice "a" "b" | append "c" "d" }} ``` Both of the above will give `[]string{a, b, c, d}`. This commit also improves the type handling in the `slice` template function. Now `slice "a" "b"` will give a `[]string` slice. The old behaviour was to return a `[]interface{}`. Fixes #5190 --- resource/resource.go | 32 ++++++++++++++++++++++++++++++++ resource/transform.go | 4 ++++ 2 files changed, 36 insertions(+) (limited to 'resource') diff --git a/resource/resource.go b/resource/resource.go index 9a974e912..dd9cbbd41 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -28,6 +28,7 @@ import ( "github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/tpl" + "github.com/gohugoio/hugo/common/collections" "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/common/loggers" @@ -49,6 +50,7 @@ var ( _ Cloner = (*genericResource)(nil) _ ResourcesLanguageMerger = (*Resources)(nil) _ permalinker = (*genericResource)(nil) + _ collections.Slicer = (*genericResource)(nil) ) var noData = make(map[string]interface{}) @@ -150,6 +152,11 @@ type ReadSeekCloserResource interface { // I.e. both pages and images etc. type Resources []Resource +// ResourcesConverter converts a given slice of Resource objects to Resources. +type ResourcesConverter interface { + ToResources() Resources +} + // ByType returns resources of a given resource type (ie. "image"). func (r Resources) ByType(tp string) Resources { var filtered Resources @@ -550,6 +557,7 @@ func (l *publishOnce) publish(s Source) error { // genericResource represents a generic linkable resource. type genericResource struct { + commonResource resourcePathDescriptor title string @@ -586,6 +594,9 @@ type genericResource struct { *publishOnce } +type commonResource struct { +} + func (l *genericResource) Data() interface{} { return noData } @@ -621,6 +632,27 @@ func (l genericResource) WithNewBase(base string) Resource { return &l } +// Slice is not meant to be used externally. It's a bridge function +// for the template functions. See collections.Slice. +func (commonResource) Slice(in interface{}) (interface{}, error) { + switch items := in.(type) { + case Resources: + return items, nil + case []interface{}: + groups := make(Resources, len(items)) + for i, v := range items { + g, ok := v.(Resource) + if !ok { + return nil, fmt.Errorf("type %T is not a Resource", v) + } + groups[i] = g + } + return groups, nil + default: + return nil, fmt.Errorf("invalid slice type %T", items) + } +} + func (l *genericResource) initHash() error { var err error l.hashInit.Do(func() { diff --git a/resource/transform.go b/resource/transform.go index 9e6215b9e..01b05b73e 100644 --- a/resource/transform.go +++ b/resource/transform.go @@ -19,6 +19,7 @@ import ( "strconv" "strings" + "github.com/gohugoio/hugo/common/collections" "github.com/gohugoio/hugo/common/errors" "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/helpers" @@ -37,6 +38,7 @@ import ( var ( _ ContentResource = (*transformedResource)(nil) _ ReadSeekCloserResource = (*transformedResource)(nil) + _ collections.Slicer = (*transformedResource)(nil) ) func (s *Spec) Transform(r Resource, t ResourceTransformation) (Resource, error) { @@ -166,6 +168,8 @@ type transformedResourceMetadata struct { } type transformedResource struct { + commonResource + cache *ResourceCache // This is the filename inside resources/_gen/assets -- cgit v1.2.3