2016-02-25 00:52:11 +01:00
|
|
|
// Copyright 2016 The Hugo Authors. All rights reserved.
|
2015-04-05 21:03:16 +02:00
|
|
|
//
|
2016-03-10 20:59:41 +01:00
|
|
|
// Portions Copyright The Go Authors.
|
|
|
|
|
2015-11-23 22:16:36 -05:00
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
2015-04-05 21:03:16 +02:00
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
2015-11-23 22:16:36 -05:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2015-04-05 21:03:16 +02:00
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2017-02-17 13:30:50 +01:00
|
|
|
package tplimpl
|
2015-04-05 21:03:16 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"html/template"
|
2016-03-13 23:17:42 -05:00
|
|
|
"sync"
|
2015-05-26 19:33:32 +09:00
|
|
|
|
2017-03-13 17:55:02 -05:00
|
|
|
"github.com/spf13/cast"
|
|
|
|
"github.com/spf13/hugo/tpl/compare"
|
|
|
|
)
|
2016-10-10 17:03:30 -05:00
|
|
|
|
|
|
|
// Get retrieves partial output from the cache based upon the partial name.
|
|
|
|
// If the partial is not found in the cache, the partial is rendered and added
|
|
|
|
// to the cache.
|
2017-03-27 20:43:49 +02:00
|
|
|
func (t *templateFuncster) Get(key, name string, context interface{}) (p interface{}, err error) {
|
2016-10-10 17:03:30 -05:00
|
|
|
var ok bool
|
|
|
|
|
2017-01-10 10:55:03 +01:00
|
|
|
t.cachedPartials.RLock()
|
|
|
|
p, ok = t.cachedPartials.p[key]
|
|
|
|
t.cachedPartials.RUnlock()
|
2016-10-10 17:03:30 -05:00
|
|
|
|
|
|
|
if ok {
|
2017-03-27 20:43:49 +02:00
|
|
|
return
|
2016-10-10 17:03:30 -05:00
|
|
|
}
|
|
|
|
|
2017-01-10 10:55:03 +01:00
|
|
|
t.cachedPartials.Lock()
|
|
|
|
if p, ok = t.cachedPartials.p[key]; !ok {
|
|
|
|
t.cachedPartials.Unlock()
|
2017-03-27 20:43:49 +02:00
|
|
|
p, err = t.partial(name, context)
|
2017-01-10 10:55:03 +01:00
|
|
|
|
|
|
|
t.cachedPartials.Lock()
|
|
|
|
t.cachedPartials.p[key] = p
|
2017-01-17 12:51:24 -06:00
|
|
|
|
2016-10-10 17:03:30 -05:00
|
|
|
}
|
2017-01-10 10:55:03 +01:00
|
|
|
t.cachedPartials.Unlock()
|
2016-10-10 17:03:30 -05:00
|
|
|
|
2017-03-27 20:43:49 +02:00
|
|
|
return
|
2016-10-10 17:03:30 -05:00
|
|
|
}
|
|
|
|
|
2017-03-13 17:55:02 -05:00
|
|
|
// partialCache represents a cache of partials protected by a mutex.
|
|
|
|
type partialCache struct {
|
|
|
|
sync.RWMutex
|
|
|
|
p map[string]interface{}
|
|
|
|
}
|
|
|
|
|
2016-10-10 17:03:30 -05:00
|
|
|
// partialCached executes and caches partial templates. An optional variant
|
|
|
|
// string parameter (a string slice actually, but be only use a variadic
|
|
|
|
// argument to make it optional) can be passed so that a given partial can have
|
|
|
|
// multiple uses. The cache is created with name+variant as the key.
|
2017-03-27 20:43:49 +02:00
|
|
|
func (t *templateFuncster) partialCached(name string, context interface{}, variant ...string) (interface{}, error) {
|
2016-10-10 17:03:30 -05:00
|
|
|
key := name
|
|
|
|
if len(variant) > 0 {
|
|
|
|
for i := 0; i < len(variant); i++ {
|
|
|
|
key += variant[i]
|
|
|
|
}
|
|
|
|
}
|
2017-01-10 10:55:03 +01:00
|
|
|
return t.Get(key, name, context)
|
2016-10-10 17:03:30 -05:00
|
|
|
}
|
|
|
|
|
2017-01-10 10:55:03 +01:00
|
|
|
func (t *templateFuncster) initFuncMap() {
|
2017-01-10 01:36:59 +01:00
|
|
|
funcMap := template.FuncMap{
|
2017-03-13 17:55:02 -05:00
|
|
|
// Namespaces
|
|
|
|
"collections": t.collections.Namespace,
|
|
|
|
"crypto": t.crypto.Namespace,
|
|
|
|
"encoding": t.encoding.Namespace,
|
|
|
|
"images": t.images.Namespace,
|
|
|
|
"inflect": t.inflect.Namespace,
|
|
|
|
"math": t.math.Namespace,
|
|
|
|
"os": t.os.Namespace,
|
|
|
|
"safe": t.safe.Namespace,
|
|
|
|
"strings": t.strings.Namespace,
|
|
|
|
//"time": t.time.Namespace,
|
|
|
|
"transform": t.transform.Namespace,
|
|
|
|
"urls": t.urls.Namespace,
|
|
|
|
|
|
|
|
"absURL": t.urls.AbsURL,
|
|
|
|
"absLangURL": t.urls.AbsLangURL,
|
|
|
|
"add": t.math.Add,
|
|
|
|
"after": t.collections.After,
|
|
|
|
"apply": t.collections.Apply,
|
|
|
|
"base64Decode": t.encoding.Base64Decode,
|
|
|
|
"base64Encode": t.encoding.Base64Encode,
|
|
|
|
"chomp": t.strings.Chomp,
|
|
|
|
"countrunes": t.strings.CountRunes,
|
|
|
|
"countwords": t.strings.CountWords,
|
|
|
|
"default": compare.Default,
|
|
|
|
"dateFormat": t.time.Format,
|
|
|
|
"delimit": t.collections.Delimit,
|
|
|
|
"dict": t.collections.Dictionary,
|
|
|
|
"div": t.math.Div,
|
|
|
|
"echoParam": t.collections.EchoParam,
|
|
|
|
"emojify": t.transform.Emojify,
|
|
|
|
"eq": compare.Eq,
|
|
|
|
"findRE": t.strings.FindRE,
|
|
|
|
"first": t.collections.First,
|
|
|
|
"ge": compare.Ge,
|
|
|
|
"getCSV": t.data.GetCSV,
|
|
|
|
"getJSON": t.data.GetJSON,
|
|
|
|
"getenv": t.os.Getenv,
|
|
|
|
"gt": compare.Gt,
|
|
|
|
"hasPrefix": t.strings.HasPrefix,
|
|
|
|
"highlight": t.transform.Highlight,
|
|
|
|
"htmlEscape": t.transform.HTMLEscape,
|
|
|
|
"htmlUnescape": t.transform.HTMLUnescape,
|
|
|
|
"humanize": t.inflect.Humanize,
|
|
|
|
"imageConfig": t.images.Config,
|
|
|
|
"in": t.collections.In,
|
|
|
|
"index": t.collections.Index,
|
2016-10-10 17:03:30 -05:00
|
|
|
"int": func(v interface{}) (int, error) { return cast.ToIntE(v) },
|
2017-03-13 17:55:02 -05:00
|
|
|
"intersect": t.collections.Intersect,
|
|
|
|
"isSet": t.collections.IsSet,
|
|
|
|
"isset": t.collections.IsSet,
|
|
|
|
"jsonify": t.encoding.Jsonify,
|
|
|
|
"last": t.collections.Last,
|
|
|
|
"le": compare.Le,
|
|
|
|
"lower": t.strings.ToLower,
|
|
|
|
"lt": compare.Lt,
|
|
|
|
"markdownify": t.transform.Markdownify,
|
|
|
|
"md5": t.crypto.MD5,
|
|
|
|
"mod": t.math.Mod,
|
|
|
|
"modBool": t.math.ModBool,
|
|
|
|
"mul": t.math.Mul,
|
|
|
|
"ne": compare.Ne,
|
|
|
|
"now": t.time.Now,
|
2017-03-27 20:43:49 +02:00
|
|
|
"partial": t.partial,
|
2017-01-10 10:55:03 +01:00
|
|
|
"partialCached": t.partialCached,
|
2017-03-13 17:55:02 -05:00
|
|
|
"plainify": t.transform.Plainify,
|
|
|
|
"pluralize": t.inflect.Pluralize,
|
2017-03-07 14:11:03 -06:00
|
|
|
"print": fmt.Sprint,
|
|
|
|
"printf": fmt.Sprintf,
|
|
|
|
"println": fmt.Sprintln,
|
2017-03-13 17:55:02 -05:00
|
|
|
"querify": t.collections.Querify,
|
|
|
|
"readDir": t.os.ReadDir,
|
|
|
|
"readFile": t.os.ReadFile,
|
|
|
|
"ref": t.urls.Ref,
|
|
|
|
"relURL": t.urls.RelURL,
|
|
|
|
"relLangURL": t.urls.RelLangURL,
|
|
|
|
"relref": t.urls.RelRef,
|
|
|
|
"replace": t.strings.Replace,
|
|
|
|
"replaceRE": t.strings.ReplaceRE,
|
|
|
|
"safeCSS": t.safe.CSS,
|
|
|
|
"safeHTML": t.safe.HTML,
|
|
|
|
"safeHTMLAttr": t.safe.HTMLAttr,
|
|
|
|
"safeJS": t.safe.JS,
|
|
|
|
"safeJSStr": t.safe.JSStr,
|
|
|
|
"safeURL": t.safe.URL,
|
|
|
|
"sanitizeURL": t.safe.SanitizeURL,
|
|
|
|
"sanitizeurl": t.safe.SanitizeURL,
|
|
|
|
"seq": t.collections.Seq,
|
|
|
|
"sha1": t.crypto.SHA1,
|
|
|
|
"sha256": t.crypto.SHA256,
|
|
|
|
"shuffle": t.collections.Shuffle,
|
|
|
|
"singularize": t.inflect.Singularize,
|
|
|
|
"slice": t.collections.Slice,
|
|
|
|
"slicestr": t.strings.SliceString,
|
|
|
|
"sort": t.collections.Sort,
|
|
|
|
"split": t.strings.Split,
|
|
|
|
"string": func(v interface{}) (string, error) { return cast.ToStringE(v) },
|
|
|
|
"sub": t.math.Sub,
|
|
|
|
"substr": t.strings.Substr,
|
|
|
|
"time": t.time.AsTime,
|
|
|
|
"title": t.strings.Title,
|
|
|
|
"trim": t.strings.Trim,
|
|
|
|
"truncate": t.strings.Truncate,
|
|
|
|
"union": t.collections.Union,
|
|
|
|
"upper": t.strings.ToUpper,
|
|
|
|
"urlize": t.PathSpec.URLize,
|
|
|
|
"where": t.collections.Where,
|
|
|
|
"i18n": t.lang.Translate,
|
|
|
|
"T": t.lang.T,
|
2015-04-05 21:03:16 +02:00
|
|
|
}
|
2017-01-10 01:36:59 +01:00
|
|
|
|
2017-01-10 10:55:03 +01:00
|
|
|
t.funcMap = funcMap
|
2017-04-15 11:33:53 +02:00
|
|
|
t.Tmpl.(*templateHandler).setFuncs(funcMap)
|
2017-03-13 17:55:02 -05:00
|
|
|
t.collections.Funcs(funcMap)
|
2015-04-05 21:03:16 +02:00
|
|
|
}
|