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