ref: 52bf8f90958e75007ca0a2761edc6ca331ca3280
parent: 75dd596e6c38466fcb97a8b9dc9eb20fc2fb7fd6
author: Bjørn Erik Pedersen <[email protected]>
date: Tue Jul 26 10:44:37 EDT 2016
Rework the i18n template func handling Setting the language to use when loading the language bundles just doesn't work. The template system is unfortanetely a global, and the last languate processed won ...
--- a/hugolib/i18n.go
+++ b/hugolib/i18n.go
@@ -19,18 +19,20 @@
"github.com/spf13/hugo/tpl"
)
-func loadI18n(sources []source.Input, lang string) (err error) {
+func loadI18n(sources []source.Input) error {
i18nBundle := bundle.New()
+
for _, currentSource := range sources {
for _, r := range currentSource.Files() {
- err = i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes())
+ err := i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes())
if err != nil {
- return
+ return err
}
}
}
- tpl.SetI18nTfunc(lang, i18nBundle)
+ tpl.SetI18nTfuncs(i18nBundle)
return nil
+
}
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -395,11 +395,20 @@
s.timer.Step(step)
}
+func (s *Site) preRender() error {
+ return tpl.SetTranslateLang(s.Lang.Lang)
+}
+
func (s *Site) Build() (err error) {
+
if err = s.Process(); err != nil {
return
}
+ if err = s.preRender(); err != nil {
+ return
+ }
+
if err = s.Render(); err != nil {
// Better reporting when the template is missing (commit 2bbecc7b)
jww.ERROR.Printf("Error rendering site: %s", err)
@@ -423,7 +432,10 @@
}
func (s *Site) ReBuild(events []fsnotify.Event) error {
+ // TODO(bep) multilingual this needs some rethinking with multiple sites
+
s.timerStep("initialize rebuild")
+
// First we need to determine what changed
sourceChanged := []fsnotify.Event{}
@@ -571,6 +583,10 @@
s.timerStep("build taxonomies")
}
+ if err := s.preRender(); err != nil {
+ return err
+ }
+
// Once the appropriate prep step is done we render the entire site
if err = s.Render(); err != nil {
// Better reporting when the template is missing (commit 2bbecc7b)
@@ -717,10 +733,11 @@
themeI18nDir, err := helpers.GetThemeI18nDirPath()
if err == nil {
+ // TODO(bep) multilingo what is this?
i18nSources = []source.Input{&source.Filesystem{Base: themeI18nDir}, i18nSources[0]}
}
- if err = loadI18n(i18nSources, s.currentLanguageString()); err != nil {
+ if err = loadI18n(i18nSources); err != nil {
return
}
s.timerStep("load i18n")
--- a/tpl/template_i18n.go
+++ b/tpl/template_i18n.go
@@ -20,28 +20,46 @@
jww "github.com/spf13/jwalterweatherman"
)
-var i18nTfunc bundle.TranslateFunc
+type translate struct {
+ translateFuncs map[string]bundle.TranslateFunc
-func SetI18nTfunc(lang string, bndl *bundle.Bundle) {
- tFunc, err := bndl.Tfunc(lang)
- if err == nil {
- i18nTfunc = tFunc
- return
+ current bundle.TranslateFunc
+}
+
+var translater *translate = &translate{translateFuncs: make(map[string]bundle.TranslateFunc)}
+
+// 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 := translater.translateFuncs[lang]; ok {
+ translater.current = f
+ return nil
}
+ return fmt.Errorf("Translation func for language %v not found", lang)
+}
- jww.WARN.Printf("could not load translations for language %q (%s), will not translate!\n", lang, err.Error())
- i18nTfunc = bundle.TranslateFunc(func(id string, args ...interface{}) string {
- // TODO: depending on the site mode, we might want to fall back on the default
- // language's translation.
- // TODO: eventually, we could add --i18n-warnings and print something when
- // such things happen.
- return fmt.Sprintf("[i18n: %s]", id)
- })
+func SetI18nTfuncs(bndl *bundle.Bundle) {
+ for _, lang := range bndl.LanguageTags() {
+ tFunc, err := bndl.Tfunc(lang)
+ if err == nil {
+ translater.translateFuncs[lang] = tFunc
+ continue
+ }
+ jww.WARN.Printf("could not load translations for language %q (%s), will not translate!\n", lang, err.Error())
+ translater.translateFuncs[lang] = bundle.TranslateFunc(func(id string, args ...interface{}) string {
+ // TODO: depending on the site mode, we might want to fall back on the default
+ // language's translation.
+ // TODO: eventually, we could add --i18n-warnings and print something when
+ // such things happen.
+ return fmt.Sprintf("[i18n: %s]", id)
+ })
+ }
+
}
func I18nTranslate(id string, args ...interface{}) (string, error) {
- if i18nTfunc == nil {
+ if translater == nil {
return "", fmt.Errorf("i18n not initialized, have you configured everything properly?")
}
- return i18nTfunc(id, args...), nil
+ return translater.current(id, args...), nil
}