diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2021-10-20 10:11:48 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-04-05 18:00:44 +0200 |
commit | e58a540895c28b8884823dcb1b64c272422f9923 (patch) | |
tree | 3fefb267f87e61a969a6ccf776d75fe64b50b2b1 /resources/resource/resources.go | |
parent | 20162518c450770ebfd54e0e987f34a5cccf236b (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/resource/resources.go')
-rw-r--r-- | resources/resource/resources.go | 92 |
1 files changed, 83 insertions, 9 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 +} |