shithub: hugo

Download patch

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
 }