mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-22 21:42:50 +02:00
@@ -40,6 +40,8 @@ import (
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
|
||||
"github.com/bep/inflect"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
@@ -57,6 +59,7 @@ import (
|
||||
type templateFuncster struct {
|
||||
funcMap template.FuncMap
|
||||
cachedPartials partialCache
|
||||
image *imageHandler
|
||||
*deps.Deps
|
||||
}
|
||||
|
||||
@@ -64,6 +67,7 @@ func newTemplateFuncster(deps *deps.Deps) *templateFuncster {
|
||||
return &templateFuncster{
|
||||
Deps: deps,
|
||||
cachedPartials: partialCache{p: make(map[string]template.HTML)},
|
||||
image: &imageHandler{fs: deps.Fs, imageConfigCache: map[string]image.Config{}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,64 +399,43 @@ func intersect(l1, l2 interface{}) (interface{}, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// ResetCaches resets all caches that might be used during build.
|
||||
// TODO(bep) globals move image config cache to funcster
|
||||
func ResetCaches() {
|
||||
resetImageConfigCache()
|
||||
}
|
||||
|
||||
// imageConfigCache is a lockable cache for image.Config objects. It must be
|
||||
// locked before reading or writing to config.
|
||||
type imageConfigCache struct {
|
||||
config map[string]image.Config
|
||||
type imageHandler struct {
|
||||
imageConfigCache map[string]image.Config
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
var defaultImageConfigCache = imageConfigCache{
|
||||
config: map[string]image.Config{},
|
||||
}
|
||||
|
||||
// resetImageConfigCache initializes and resets the imageConfig cache for the
|
||||
// imageConfig template function. This should be run once before every batch of
|
||||
// template renderers so the cache is cleared for new data.
|
||||
func resetImageConfigCache() {
|
||||
defaultImageConfigCache.Lock()
|
||||
defer defaultImageConfigCache.Unlock()
|
||||
|
||||
defaultImageConfigCache.config = map[string]image.Config{}
|
||||
fs *hugofs.Fs
|
||||
}
|
||||
|
||||
// imageConfig returns the image.Config for the specified path relative to the
|
||||
// working directory. resetImageConfigCache must be run beforehand.
|
||||
func (t *templateFuncster) imageConfig(path interface{}) (image.Config, error) {
|
||||
// working directory.
|
||||
func (ic *imageHandler) config(path interface{}) (image.Config, error) {
|
||||
filename, err := cast.ToStringE(path)
|
||||
if err != nil {
|
||||
return image.Config{}, err
|
||||
}
|
||||
|
||||
if filename == "" {
|
||||
return image.Config{}, errors.New("imageConfig needs a filename")
|
||||
return image.Config{}, errors.New("config needs a filename")
|
||||
}
|
||||
|
||||
// Check cache for image config.
|
||||
defaultImageConfigCache.RLock()
|
||||
config, ok := defaultImageConfigCache.config[filename]
|
||||
defaultImageConfigCache.RUnlock()
|
||||
ic.RLock()
|
||||
config, ok := ic.imageConfigCache[filename]
|
||||
ic.RUnlock()
|
||||
|
||||
if ok {
|
||||
return config, nil
|
||||
}
|
||||
|
||||
f, err := t.Fs.WorkingDir.Open(filename)
|
||||
f, err := ic.fs.WorkingDir.Open(filename)
|
||||
if err != nil {
|
||||
return image.Config{}, err
|
||||
}
|
||||
|
||||
config, _, err = image.DecodeConfig(f)
|
||||
|
||||
defaultImageConfigCache.Lock()
|
||||
defaultImageConfigCache.config[filename] = config
|
||||
defaultImageConfigCache.Unlock()
|
||||
ic.Lock()
|
||||
ic.imageConfigCache[filename] = config
|
||||
ic.Unlock()
|
||||
|
||||
return config, err
|
||||
}
|
||||
@@ -2144,7 +2127,7 @@ func (t *templateFuncster) initFuncMap() {
|
||||
"htmlEscape": htmlEscape,
|
||||
"htmlUnescape": htmlUnescape,
|
||||
"humanize": humanize,
|
||||
"imageConfig": t.imageConfig,
|
||||
"imageConfig": t.image.config,
|
||||
"in": in,
|
||||
"index": index,
|
||||
"int": func(v interface{}) (int, error) { return cast.ToIntE(v) },
|
||||
|
Reference in New Issue
Block a user