Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2021-10-20 11:11:48 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-04-05 19:00:44 +0300
commite58a540895c28b8884823dcb1b64c272422f9923 (patch)
tree3fefb267f87e61a969a6ccf776d75fe64b50b2b1 /resources
parent20162518c450770ebfd54e0e987f34a5cccf236b (diff)
resources: Create a common ResourceFinder interface
And make both .Resources and resources implement it. This gets us 2 new methods/functions, so you can now also do: * .Resources.Get * resources.ByType Note that GetRemote is not covered by this interface, as that is only available as a global template function. Fixes #8653
Diffstat (limited to 'resources')
-rw-r--r--resources/resource/resources.go92
-rw-r--r--resources/resource_factories/create/create.go25
2 files changed, 98 insertions, 19 deletions
diff --git a/resources/resource/resources.go b/resources/resource/resources.go
index aaa747194..428decf84 100644
--- a/resources/resource/resources.go
+++ b/resources/resource/resources.go
@@ -18,35 +18,64 @@ import (
"strings"
"github.com/gohugoio/hugo/hugofs/glob"
+ "github.com/spf13/cast"
)
+var _ ResourceFinder = (*Resources)(nil)
+
// Resources represents a slice of resources, which can be a mix of different types.
// I.e. both pages and images etc.
type Resources []Resource
+// var _ resource.ResourceFinder = (*Namespace)(nil)
// 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 {
+// ByType returns resources of a given resource type (e.g. "image").
+func (r Resources) ByType(typ any) Resources {
+ tpstr, err := cast.ToStringE(typ)
+ if err != nil {
+ panic(err)
+ }
var filtered Resources
for _, resource := range r {
- if resource.ResourceType() == tp {
+ if resource.ResourceType() == tpstr {
filtered = append(filtered, resource)
}
}
return filtered
}
+// Get locates the name given in Resources.
+// The search is case insensitive.
+func (r Resources) Get(name any) Resource {
+ namestr, err := cast.ToStringE(name)
+ if err != nil {
+ panic(err)
+ }
+ namestr = strings.ToLower(namestr)
+ for _, resource := range r {
+ if strings.EqualFold(namestr, resource.Name()) {
+ return resource
+ }
+ }
+ return nil
+}
+
// GetMatch finds the first Resource matching the given pattern, or nil if none found.
// See Match for a more complete explanation about the rules used.
-func (r Resources) GetMatch(pattern string) Resource {
- g, err := glob.GetGlob(pattern)
+func (r Resources) GetMatch(pattern any) Resource {
+ patternstr, err := cast.ToStringE(pattern)
+ if err != nil {
+ panic(err)
+ }
+
+ g, err := glob.GetGlob(patternstr)
if err != nil {
- return nil
+ panic(err)
}
for _, resource := range r {
@@ -67,10 +96,15 @@ func (r Resources) GetMatch(pattern string) Resource {
// Match matches by using the value of Resource.Name, which, by default, is a filename with
// path relative to the bundle root with Unix style slashes (/) and no leading slash, e.g. "images/logo.png".
// See https://github.com/gobwas/glob for the full rules set.
-func (r Resources) Match(pattern string) Resources {
- g, err := glob.GetGlob(pattern)
+func (r Resources) Match(pattern any) Resources {
+ patternstr, err := cast.ToStringE(pattern)
if err != nil {
- return nil
+ panic(err)
+ }
+
+ g, err := glob.GetGlob(patternstr)
+ if err != nil {
+ panic(err)
}
var matches Resources
@@ -121,3 +155,43 @@ func (r Resources) MergeByLanguageInterface(in any) (any, error) {
type Source interface {
Publish() error
}
+
+// ResourceFinder provides methods to find Resources.
+// Note that GetRemote (as found in resources.GetRemote) is
+// not covered by this interface, as this is only available as a global template function.
+type ResourceFinder interface {
+
+ // Get locates the Resource with the given name in the current context (e.g. in .Page.Resources).
+ //
+ // It returns nil if no Resource could found, panics if name is invalid.
+ Get(name any) Resource
+
+ // GetMatch finds the first Resource matching the given pattern, or nil if none found.
+ //
+ // See Match for a more complete explanation about the rules used.
+ //
+ // It returns nil if no Resource could found, panics if pattern is invalid.
+ GetMatch(pattern any) Resource
+
+ // Match gets all resources matching the given base path prefix, e.g
+ // "*.png" will match all png files. The "*" does not match path delimiters (/),
+ // so if you organize your resources in sub-folders, you need to be explicit about it, e.g.:
+ // "images/*.png". To match any PNG image anywhere in the bundle you can do "**.png", and
+ // to match all PNG images below the images folder, use "images/**.jpg".
+ //
+ // The matching is case insensitive.
+ //
+ // Match matches by using a relative pathwith Unix style slashes (/) and no
+ // leading slash, e.g. "images/logo.png".
+ //
+ // See https://github.com/gobwas/glob for the full rules set.
+ //
+ // See Match for a more complete explanation about the rules used.
+ //
+ // It returns nil if no Resources could found, panics if pattern is invalid.
+ Match(pattern any) Resources
+
+ // ByType returns resources of a given resource type (e.g. "image").
+ // It returns nil if no Resources could found, panics if typ is invalid.
+ ByType(typ any) Resources
+}
diff --git a/resources/resource_factories/create/create.go b/resources/resource_factories/create/create.go
index f8e7e18db..3827411a9 100644
--- a/resources/resource_factories/create/create.go
+++ b/resources/resource_factories/create/create.go
@@ -65,26 +65,27 @@ func (c *Client) Get(filename string) (resource.Resource, error) {
// Match gets the resources matching the given pattern from the assets filesystem.
func (c *Client) Match(pattern string) (resource.Resources, error) {
- return c.match(pattern, false)
+ return c.match("__match", pattern, nil, false)
+}
+
+func (c *Client) ByType(tp string) resource.Resources {
+ res, err := c.match(path.Join("_byType", tp), "**", func(r resource.Resource) bool { return r.ResourceType() == tp }, false)
+ if err != nil {
+ panic(err)
+ }
+ return res
}
// GetMatch gets first resource matching the given pattern from the assets filesystem.
func (c *Client) GetMatch(pattern string) (resource.Resource, error) {
- res, err := c.match(pattern, true)
+ res, err := c.match("__get-match", pattern, nil, true)
if err != nil || len(res) == 0 {
return nil, err
}
return res[0], err
}
-func (c *Client) match(pattern string, firstOnly bool) (resource.Resources, error) {
- var name string
- if firstOnly {
- name = "__get-match"
- } else {
- name = "__match"
- }
-
+func (c *Client) match(name, pattern string, matchFunc func(r resource.Resource) bool, firstOnly bool) (resource.Resources, error) {
pattern = glob.NormalizePath(pattern)
partitions := glob.FilterGlobParts(strings.Split(pattern, "/"))
if len(partitions) == 0 {
@@ -110,6 +111,10 @@ func (c *Client) match(pattern string, firstOnly bool) (resource.Resources, erro
return true, err
}
+ if matchFunc != nil && !matchFunc(r) {
+ return false, nil
+ }
+
res = append(res, r)
return firstOnly, nil