diff --git a/hugolib/i18n.go b/hugolib/i18n.go index cb5061501..8caf30d7c 100644 --- a/hugolib/i18n.go +++ b/hugolib/i18n.go @@ -19,18 +19,20 @@ import ( "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 + } diff --git a/hugolib/site.go b/hugolib/site.go index bbaa1e019..d902f693e 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -395,11 +395,20 @@ func (s *Site) timerStep(step string) { 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) Build() (err error) { } 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 @@ func (s *Site) ReBuild(events []fsnotify.Event) error { 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 @@ func (s *Site) Process() (err error) { 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") diff --git a/tpl/template_i18n.go b/tpl/template_i18n.go index 3b0f0cb63..5590fe29a 100644 --- a/tpl/template_i18n.go +++ b/tpl/template_i18n.go @@ -20,28 +20,46 @@ import ( 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) +} + +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) + }) } - 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 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 }