diff --git a/i18n/i18n_test.go b/i18n/i18n_test.go index 6a9d362b0..9e7aed039 100644 --- a/i18n/i18n_test.go +++ b/i18n/i18n_test.go @@ -23,9 +23,11 @@ import ( "github.com/gohugoio/hugo/config" "github.com/nicksnyder/go-i18n/i18n/bundle" + "github.com/nicksnyder/go-i18n/i18n/language" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" "github.com/stretchr/testify/require" + "strings" ) var logger = jww.NewNotepad(jww.LevelError, jww.LevelError, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime) @@ -137,10 +139,29 @@ var i18nTests = []i18nTest{ expected: "hello", expectedFlag: "[i18n] hello", }, + // Non Unicode CLDR language code + { + data: map[string][]byte{ + "dk.toml": []byte("[hello]\nother = \"hej\""), + }, + args: nil, + lang: "dk", + id: "hello", + expected: "hej", + expectedFlag: "hej", + }, } func doTestI18nTranslate(t *testing.T, test i18nTest, cfg config.Provider) string { i18nBundle := bundle.New() + ids := []string{} + + for file := range test.data { + id := strings.TrimSuffix(file, ".toml") + ids = append(ids, id) + } + + language.RegisterPluralSpec(ids, &language.PluralSpec{}) for file, content := range test.data { err := i18nBundle.ParseTranslationFileBytes(file, content) diff --git a/i18n/translationProvider.go b/i18n/translationProvider.go index 9947d3ce5..663a8dd5e 100644 --- a/i18n/translationProvider.go +++ b/i18n/translationProvider.go @@ -15,12 +15,18 @@ package i18n import ( "fmt" + "sync" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/source" "github.com/nicksnyder/go-i18n/i18n/bundle" + "github.com/nicksnyder/go-i18n/i18n/language" ) +// Unfortunately this needs to be global, see +// https://github.com/nicksnyder/go-i18n/issues/82 +var tpMu sync.Mutex + // TranslationProvider provides translation handling, i.e. loading // of bundles etc. type TranslationProvider struct { @@ -34,6 +40,9 @@ func NewTranslationProvider() *TranslationProvider { // Update updates the i18n func in the provided Deps. func (tp *TranslationProvider) Update(d *deps.Deps) error { + tpMu.Lock() + defer tpMu.Unlock() + dir := d.PathSpec.AbsPathify(d.Cfg.GetString("i18nDir")) sp := source.NewSourceSpec(d.Cfg, d.Fs) sources := []source.Input{sp.NewFilesystem(dir)} @@ -48,6 +57,17 @@ func (tp *TranslationProvider) Update(d *deps.Deps) error { i18nBundle := bundle.New() + langs := []string{} + for _, currentSource := range sources { + for _, r := range currentSource.Files() { + langs = append(langs, r.BaseFileName()) + } + } + // We need to register all language codes as "plural spec" to prevent errors with unknown language codes. + // see https://github.com/gohugoio/hugo/issues/3564 + ps := &language.PluralSpec{} + language.RegisterPluralSpec(langs, ps) + for _, currentSource := range sources { for _, r := range currentSource.Files() { err := i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes())