Avoid reading from Viper for path and URL funcs

The gain, given the "real sites benchmark" below, is obvious:

```
benchmark           old ns/op       new ns/op       delta
BenchmarkHugo-4     14497594101     13084156335     -9.75%

benchmark           old allocs     new allocs     delta
BenchmarkHugo-4     57404335       48282002       -15.89%

benchmark           old bytes       new bytes      delta
BenchmarkHugo-4     9933505624      9721984424     -2.13%
```

Fixes #2495
This commit is contained in:
Bjørn Erik Pedersen
2016-10-24 13:45:30 +02:00
committed by GitHub
parent dffd7da07c
commit a10b2cd372
26 changed files with 348 additions and 90 deletions

View File

@@ -94,6 +94,10 @@ func New() Template {
localTemplates = &templates.Template
// The URL funcs in the funcMap is somewhat language dependent,
// so need to be reinit per site.
initFuncMap()
for k, v := range funcMap {
amber.FuncMap[k] = v
}

View File

@@ -47,7 +47,9 @@ import (
"github.com/spf13/viper"
)
var funcMap template.FuncMap
var (
funcMap template.FuncMap
)
// eq returns the boolean truth of arg1 == arg2.
func eq(x, y interface{}) bool {
@@ -1940,7 +1942,7 @@ func absURL(a interface{}) (template.HTML, error) {
if err != nil {
return "", nil
}
return template.HTML(helpers.AbsURL(s, false)), nil
return template.HTML(helpers.CurrentPathSpec().AbsURL(s, false)), nil
}
func relURL(a interface{}) (template.HTML, error) {
@@ -1948,10 +1950,10 @@ func relURL(a interface{}) (template.HTML, error) {
if err != nil {
return "", nil
}
return template.HTML(helpers.RelURL(s, false)), nil
return template.HTML(helpers.CurrentPathSpec().RelURL(s, false)), nil
}
func init() {
func initFuncMap() {
funcMap = template.FuncMap{
"absURL": absURL,
"absLangURL": func(i interface{}) (template.HTML, error) {
@@ -1959,7 +1961,7 @@ func init() {
if err != nil {
return "", err
}
return template.HTML(helpers.AbsURL(s, true)), nil
return template.HTML(helpers.CurrentPathSpec().AbsURL(s, true)), nil
},
"add": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '+') },
"after": after,
@@ -2020,7 +2022,7 @@ func init() {
if err != nil {
return "", err
}
return template.HTML(helpers.RelURL(s, true)), nil
return template.HTML(helpers.CurrentPathSpec().RelURL(s, true)), nil
},
"relref": relRef,
"replace": replace,
@@ -2047,7 +2049,7 @@ func init() {
"time": asTime,
"trim": trim,
"upper": func(a string) string { return strings.ToUpper(a) },
"urlize": helpers.URLize,
"urlize": helpers.CurrentPathSpec().URLize,
"where": where,
"i18n": I18nTranslate,
"T": I18nTranslate,

View File

@@ -63,6 +63,11 @@ func tstIsLt(tp tstCompareType) bool {
return tp == tstLt || tp == tstLe
}
func tstInitTemplates() {
viper.Set("CurrentContentLanguage", helpers.NewLanguage("en"))
helpers.ResetConfigProvider()
}
func TestFuncsInTemplate(t *testing.T) {
viper.Reset()
@@ -234,6 +239,8 @@ urlize: bat-man
viper.Set("baseURL", "http://mysite.com/hugo/")
tstInitTemplates()
if err != nil {
t.Fatal("Got error on parse", err)
}
@@ -2498,6 +2505,7 @@ func TestPartialCached(t *testing.T) {
data.Section = "blog"
data.Params = map[string]interface{}{"langCode": "en"}
tstInitTemplates()
InitializeT()
for i, tc := range testCases {
var tmp string

View File

@@ -25,6 +25,7 @@ import (
var (
Logi18nWarnings bool
i18nWarningLogger = helpers.NewDistinctFeedbackLogger()
currentLanguage *helpers.Language
)
type translate struct {
@@ -37,11 +38,12 @@ var translator *translate
// SetTranslateLang sets the translations language to use during template processing.
// This construction is unfortunate, but the template system is currently global.
func SetTranslateLang(lang string) error {
if f, ok := translator.translateFuncs[lang]; ok {
func SetTranslateLang(language *helpers.Language) error {
currentLanguage = language
if f, ok := translator.translateFuncs[language.Lang]; ok {
translator.current = f
} else {
jww.WARN.Printf("Translation func for language %v not found, use default.", lang)
jww.WARN.Printf("Translation func for language %v not found, use default.", language.Lang)
translator.current = translator.translateFuncs[viper.GetString("DefaultContentLanguage")]
}
return nil

View File

@@ -17,6 +17,7 @@ import (
"testing"
"github.com/nicksnyder/go-i18n/i18n/bundle"
"github.com/spf13/hugo/helpers"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)
@@ -116,7 +117,7 @@ func doTestI18nTranslate(t *testing.T, data map[string][]byte, lang, id string,
}
SetI18nTfuncs(i18nBundle)
SetTranslateLang(lang)
SetTranslateLang(helpers.NewLanguage(lang))
translated, err := I18nTranslate(id, args)
if err != nil {
@@ -129,6 +130,7 @@ func TestI18nTranslate(t *testing.T) {
var actual, expected string
viper.SetDefault("DefaultContentLanguage", "en")
viper.Set("CurrentContentLanguage", helpers.NewLanguage("en"))
// Test without and with placeholders
for _, enablePlaceholders := range []bool{false, true} {