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 ...
This commit is contained in:
Bjørn Erik Pedersen 2016-07-26 14:44:37 +02:00
parent 75dd596e6c
commit 52bf8f9095
3 changed files with 58 additions and 21 deletions

View file

@ -19,18 +19,20 @@ import (
"github.com/spf13/hugo/tpl" "github.com/spf13/hugo/tpl"
) )
func loadI18n(sources []source.Input, lang string) (err error) { func loadI18n(sources []source.Input) error {
i18nBundle := bundle.New() i18nBundle := bundle.New()
for _, currentSource := range sources { for _, currentSource := range sources {
for _, r := range currentSource.Files() { for _, r := range currentSource.Files() {
err = i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes()) err := i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes())
if err != nil { if err != nil {
return return err
} }
} }
} }
tpl.SetI18nTfunc(lang, i18nBundle) tpl.SetI18nTfuncs(i18nBundle)
return nil return nil
} }

View file

@ -395,11 +395,20 @@ func (s *Site) timerStep(step string) {
s.timer.Step(step) s.timer.Step(step)
} }
func (s *Site) preRender() error {
return tpl.SetTranslateLang(s.Lang.Lang)
}
func (s *Site) Build() (err error) { func (s *Site) Build() (err error) {
if err = s.Process(); err != nil { if err = s.Process(); err != nil {
return return
} }
if err = s.preRender(); err != nil {
return
}
if err = s.Render(); err != nil { if err = s.Render(); err != nil {
// Better reporting when the template is missing (commit 2bbecc7b) // Better reporting when the template is missing (commit 2bbecc7b)
jww.ERROR.Printf("Error rendering site: %s", err) jww.ERROR.Printf("Error rendering site: %s", err)
@ -423,7 +432,10 @@ func (s *Site) Build() (err error) {
} }
func (s *Site) ReBuild(events []fsnotify.Event) error { func (s *Site) ReBuild(events []fsnotify.Event) error {
// TODO(bep) multilingual this needs some rethinking with multiple sites
s.timerStep("initialize rebuild") s.timerStep("initialize rebuild")
// First we need to determine what changed // First we need to determine what changed
sourceChanged := []fsnotify.Event{} sourceChanged := []fsnotify.Event{}
@ -571,6 +583,10 @@ func (s *Site) ReBuild(events []fsnotify.Event) error {
s.timerStep("build taxonomies") s.timerStep("build taxonomies")
} }
if err := s.preRender(); err != nil {
return err
}
// Once the appropriate prep step is done we render the entire site // Once the appropriate prep step is done we render the entire site
if err = s.Render(); err != nil { if err = s.Render(); err != nil {
// Better reporting when the template is missing (commit 2bbecc7b) // Better reporting when the template is missing (commit 2bbecc7b)
@ -717,10 +733,11 @@ func (s *Site) Process() (err error) {
themeI18nDir, err := helpers.GetThemeI18nDirPath() themeI18nDir, err := helpers.GetThemeI18nDirPath()
if err == nil { if err == nil {
// TODO(bep) multilingo what is this?
i18nSources = []source.Input{&source.Filesystem{Base: themeI18nDir}, i18nSources[0]} i18nSources = []source.Input{&source.Filesystem{Base: themeI18nDir}, i18nSources[0]}
} }
if err = loadI18n(i18nSources, s.currentLanguageString()); err != nil { if err = loadI18n(i18nSources); err != nil {
return return
} }
s.timerStep("load i18n") s.timerStep("load i18n")

View file

@ -20,17 +20,33 @@ import (
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
) )
var i18nTfunc bundle.TranslateFunc type translate struct {
translateFuncs map[string]bundle.TranslateFunc
func SetI18nTfunc(lang string, bndl *bundle.Bundle) { current bundle.TranslateFunc
tFunc, err := bndl.Tfunc(lang)
if err == nil {
i18nTfunc = tFunc
return
} }
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)
}
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()) 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 { 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 // TODO: depending on the site mode, we might want to fall back on the default
// language's translation. // language's translation.
// TODO: eventually, we could add --i18n-warnings and print something when // TODO: eventually, we could add --i18n-warnings and print something when
@ -39,9 +55,11 @@ func SetI18nTfunc(lang string, bndl *bundle.Bundle) {
}) })
} }
}
func I18nTranslate(id string, args ...interface{}) (string, error) { 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 "", fmt.Errorf("i18n not initialized, have you configured everything properly?")
} }
return i18nTfunc(id, args...), nil return translater.current(id, args...), nil
} }