resourcetypes.go (6229B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package resource
15
16 import (
17 "github.com/gohugoio/hugo/common/maps"
18 "github.com/gohugoio/hugo/langs"
19 "github.com/gohugoio/hugo/media"
20
21 "github.com/gohugoio/hugo/common/hugio"
22 )
23
24 var (
25 _ ResourceDataProvider = (*resourceError)(nil)
26 _ ResourceError = (*resourceError)(nil)
27 )
28
29 // Cloner is for internal use.
30 type Cloner interface {
31 Clone() Resource
32 }
33
34 // OriginProvider provides the original Resource if this is wrapped.
35 // This is an internal Hugo interface and not meant for use in the templates.
36 type OriginProvider interface {
37 Origin() Resource
38 GetFieldString(pattern string) (string, bool)
39 }
40
41 // NewResourceError creates a new ResourceError.
42 func NewResourceError(err error, data any) ResourceError {
43 return &resourceError{
44 error: err,
45 data: data,
46 }
47 }
48
49 type resourceError struct {
50 error
51 data any
52 }
53
54 // The data associated with this error.
55 func (e *resourceError) Data() any {
56 return e.data
57 }
58
59 // ResourceError is the error return from .Err in Resource in error situations.
60 type ResourceError interface {
61 error
62 ResourceDataProvider
63 }
64
65 // ErrProvider provides an Err.
66 type ErrProvider interface {
67 Err() ResourceError
68 }
69
70 // Resource represents a linkable resource, i.e. a content page, image etc.
71 type Resource interface {
72 ResourceTypeProvider
73 MediaTypeProvider
74 ResourceLinksProvider
75 ResourceMetaProvider
76 ResourceParamsProvider
77 ResourceDataProvider
78 ErrProvider
79 }
80
81 type ResourceTypeProvider interface {
82 // ResourceType is the resource type. For most file types, this is the main
83 // part of the MIME type, e.g. "image", "application", "text" etc.
84 // For content pages, this value is "page".
85 ResourceType() string
86 }
87
88 type ResourceTypesProvider interface {
89 ResourceTypeProvider
90 MediaTypeProvider
91 }
92
93 type MediaTypeProvider interface {
94 // MediaType is this resource's MIME type.
95 MediaType() media.Type
96 }
97
98 type ResourceLinksProvider interface {
99 // Permalink represents the absolute link to this resource.
100 Permalink() string
101
102 // RelPermalink represents the host relative link to this resource.
103 RelPermalink() string
104 }
105
106 type ResourceMetaProvider interface {
107 // Name is the logical name of this resource. This can be set in the front matter
108 // metadata for this resource. If not set, Hugo will assign a value.
109 // This will in most cases be the base filename.
110 // So, for the image "/some/path/sunset.jpg" this will be "sunset.jpg".
111 // The value returned by this method will be used in the GetByPrefix and ByPrefix methods
112 // on Resources.
113 Name() string
114
115 // Title returns the title if set in front matter. For content pages, this will be the expected value.
116 Title() string
117 }
118
119 type ResourceParamsProvider interface {
120 // Params set in front matter for this resource.
121 Params() maps.Params
122 }
123
124 type ResourceDataProvider interface {
125 // Resource specific data set by Hugo.
126 // One example would be.Data.Digest for fingerprinted resources.
127 Data() any
128 }
129
130 // ResourcesLanguageMerger describes an interface for merging resources from a
131 // different language.
132 type ResourcesLanguageMerger interface {
133 MergeByLanguage(other Resources) Resources
134
135 // Needed for integration with the tpl package.
136 // For internal use.
137 MergeByLanguageInterface(other any) (any, error)
138 }
139
140 // Identifier identifies a resource.
141 type Identifier interface {
142 Key() string
143 }
144
145 // ContentResource represents a Resource that provides a way to get to its content.
146 // Most Resource types in Hugo implements this interface, including Page.
147 type ContentResource interface {
148 MediaType() media.Type
149 ContentProvider
150 }
151
152 // ContentProvider provides Content.
153 // This should be used with care, as it will read the file content into memory, but it
154 // should be cached as effectively as possible by the implementation.
155 type ContentProvider interface {
156 // Content returns this resource's content. It will be equivalent to reading the content
157 // that RelPermalink points to in the published folder.
158 // The return type will be contextual, and should be what you would expect:
159 // * Page: template.HTML
160 // * JSON: String
161 // * Etc.
162 Content() (any, error)
163 }
164
165 // OpenReadSeekCloser allows setting some other way (than reading from a filesystem)
166 // to open or create a ReadSeekCloser.
167 type OpenReadSeekCloser func() (hugio.ReadSeekCloser, error)
168
169 // ReadSeekCloserResource is a Resource that supports loading its content.
170 type ReadSeekCloserResource interface {
171 MediaType() media.Type
172 hugio.ReadSeekCloserProvider
173 }
174
175 // LengthProvider is a Resource that provides a length
176 // (typically the length of the content).
177 type LengthProvider interface {
178 Len() int
179 }
180
181 // LanguageProvider is a Resource in a language.
182 type LanguageProvider interface {
183 Language() *langs.Language
184 }
185
186 // TranslationKeyProvider connects translations of the same Resource.
187 type TranslationKeyProvider interface {
188 TranslationKey() string
189 }
190
191 // UnmarshableResource represents a Resource that can be unmarshaled to some other format.
192 type UnmarshableResource interface {
193 ReadSeekCloserResource
194 Identifier
195 }
196
197 type resourceTypesHolder struct {
198 mediaType media.Type
199 resourceType string
200 }
201
202 func (r resourceTypesHolder) MediaType() media.Type {
203 return r.mediaType
204 }
205
206 func (r resourceTypesHolder) ResourceType() string {
207 return r.resourceType
208 }
209
210 func NewResourceTypesProvider(mediaType media.Type, resourceType string) ResourceTypesProvider {
211 return resourceTypesHolder{mediaType: mediaType, resourceType: resourceType}
212 }
213
214 type languageHolder struct {
215 lang *langs.Language
216 }
217
218 func (l languageHolder) Language() *langs.Language {
219 return l.lang
220 }
221
222 func NewLanguageProvider(lang *langs.Language) LanguageProvider {
223 return languageHolder{lang: lang}
224 }