i18n: Support unknown language codes
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 6 Nov 2017 08:33:24 +0000 (09:33 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 6 Nov 2017 19:27:41 +0000 (20:27 +0100)
Fixes #3564

i18n/i18n_test.go
i18n/translationProvider.go

index 6a9d362b01fe1c7293de15cf157f8461a822fc86..057fc35e93ea7d40732e24b8424f7bed15e7d5bc 100644 (file)
 package i18n
 
 import (
+       "path/filepath"
        "testing"
 
+       "github.com/gohugoio/hugo/tpl/tplimpl"
+
+       "github.com/spf13/afero"
+
+       "github.com/gohugoio/hugo/deps"
+
        "io/ioutil"
        "os"
 
+       "github.com/gohugoio/hugo/helpers"
+
        "log"
 
        "github.com/gohugoio/hugo/config"
-       "github.com/nicksnyder/go-i18n/i18n/bundle"
+       "github.com/gohugoio/hugo/hugofs"
        jww "github.com/spf13/jwalterweatherman"
        "github.com/spf13/viper"
        "github.com/stretchr/testify/require"
@@ -137,22 +146,54 @@ var i18nTests = []i18nTest{
                expected:     "hello",
                expectedFlag: "[i18n] hello",
        },
+       // Unknown language code should get its plural spec from en
+       {
+               data: map[string][]byte{
+                       "en.toml": []byte(`[readingTime]
+one ="one minute read"
+other = "{{.Count}} minutes read"`),
+                       "klingon.toml": []byte(`[readingTime]
+one =  "eitt minutt med lesing"
+other = "{{ .Count }} minuttar lesing"`),
+               },
+               args:         3,
+               lang:         "klingon",
+               id:           "readingTime",
+               expected:     "3 minuttar lesing",
+               expectedFlag: "3 minuttar lesing",
+       },
 }
 
 func doTestI18nTranslate(t *testing.T, test i18nTest, cfg config.Provider) string {
-       i18nBundle := bundle.New()
+       assert := require.New(t)
+       fs := hugofs.NewMem(cfg)
+       tp := NewTranslationProvider()
+       depsCfg := newDepsConfig(tp, cfg, fs)
+       d, err := deps.New(depsCfg)
+       assert.NoError(err)
 
        for file, content := range test.data {
-               err := i18nBundle.ParseTranslationFileBytes(file, content)
-               if err != nil {
-                       t.Errorf("Error parsing translation file: %s", err)
-               }
+               err := afero.WriteFile(fs.Source, filepath.Join("i18n", file), []byte(content), 0755)
+               assert.NoError(err)
        }
 
-       translator := NewTranslator(i18nBundle, cfg, logger)
-       f := translator.Func(test.lang)
-       translated := f(test.id, test.args)
-       return translated
+       assert.NoError(d.LoadResources())
+       f := tp.t.Func(test.lang)
+       return f(test.id, test.args)
+
+}
+
+func newDepsConfig(tp *TranslationProvider, cfg config.Provider, fs *hugofs.Fs) deps.DepsCfg {
+       l := helpers.NewLanguage("en", cfg)
+       l.Set("i18nDir", "i18n")
+       return deps.DepsCfg{
+               Language:            l,
+               Cfg:                 cfg,
+               Fs:                  fs,
+               Logger:              logger,
+               TemplateProvider:    tplimpl.DefaultTemplateProvider,
+               TranslationProvider: tp,
+       }
 }
 
 func TestI18nTranslate(t *testing.T) {
index 9947d3ce52156969c5abde3cc1d07fcf587aae6d..e0eb89134aaae270472ac192778a03ac2d72d1d3 100644 (file)
 package i18n
 
 import (
+       "errors"
        "fmt"
 
        "github.com/gohugoio/hugo/deps"
        "github.com/gohugoio/hugo/source"
        "github.com/nicksnyder/go-i18n/i18n/bundle"
+       "github.com/nicksnyder/go-i18n/i18n/language"
 )
 
 // TranslationProvider provides translation handling, i.e. loading
@@ -48,6 +50,27 @@ func (tp *TranslationProvider) Update(d *deps.Deps) error {
 
        i18nBundle := bundle.New()
 
+       en := language.GetPluralSpec("en")
+       if en == nil {
+               return errors.New("The English language has vanished like an old oak table!")
+       }
+       var newLangs []string
+
+       for _, currentSource := range sources {
+               for _, r := range currentSource.Files() {
+                       currentSpec := language.GetPluralSpec(r.BaseFileName())
+                       if currentSpec == nil {
+                               // This may is a language code not supported by go-i18n, it may be
+                               // Klingon or ... not even a fake language. Make sure it works.
+                               newLangs = append(newLangs, r.BaseFileName())
+                       }
+               }
+       }
+
+       if len(newLangs) > 0 {
+               language.RegisterPluralSpec(newLangs, en)
+       }
+
        for _, currentSource := range sources {
                for _, r := range currentSource.Files() {
                        err := i18nBundle.ParseTranslationFileBytes(r.LogicalName(), r.Bytes())