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 }