vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

[feature request] Have $te check for fallback locales

Open PROgram52bc opened this issue 3 years ago • 6 comments

Suppose I have the following messages and fallback config:

messages: {
  en: {
    message: {
      hello: 'hello world',
      greeting: 'good morning'
    }
  }
},
fallbackLocale: 'en'

And with my current $i18n.locale set to "en-US", running $te will have the following output:

this.$te('hello') // => false

Would it be a bad idea to configure the default behavior of $te to take into account of the fallback locale setting?

So suppose I have the fallbackLocale set to ['es-EC', 'en'], and with $i18n.locale set to "fr", running

this.$te('hello')

should be equivalent to

(this.$te('hello', 'fr') ||
 this.$te('hello', 'es-EC') ||
 this.$te('hello', 'es') ||
 this.$te('hello', 'en'))

With that implemented, the current default behavior should still be reproduceable with this.$te('hello', this.$i18n.locale).

PROgram52bc avatar Aug 12 '20 18:08 PROgram52bc

Could you add more detail about use cases for this enhancement ?

exoego avatar Sep 08 '20 11:09 exoego

This has come up for me with enumerated values, where a property may have one of a limited number of values. Each known value is translated in the fallback locale, but I also want the behavior to be well defined if the value isn't known. For example, for data like this:

[
  {
    "type": "image",
    "name": "My Image.png"
  },
  {
    "type": "file",
    "name": "My Data.csv"
  }
]

and translations like this:

{
  "en": {
    "type": {
      "image": "Image",
      "file": "Data File"
    }
  },
  "cs": {
    "type": {
      "image": "Obrázek"
    }
  }
}

I want to implement the following behavior:

  1. If there is a translation for the type in the current locale, display that.
  2. Otherwise, if there is a translation for the type in the fallback locale, display that.
  3. Otherwise (if the type isn't known), simply display the type.

Right now I've implemented:

const path = `type.${type}`;
return this.$te(path, this.$i18n.fallbackLocale) ? this.$t(path) : type;

It wouldn't work to use this.$te() without specifying the fallback locale, because then if a translation is missing for the current locale, it won't fall back to the fallback locale. With fallback, the line would be a little simpler:

return this.$te(path) ? this.$t(path) : type;

It isn't hard to specify the fallback locale, but I didn't notice that it was necessary at first. $t() and $tc() both fall back to the fallback locale, so I assumed that $te() would as well, and I was surprised when it didn't.

matthew-white avatar Sep 08 '20 12:09 matthew-white

I am having a similar issue concerning the implicit locale fallback.

const i18n = new VueI18n({
  locale: 'en-US',
  messages: {
    en: {
      hello: 'hello world'
    }
  }
});

const key = 'hello';
console.log(i18n.t(key)); // hello world
console.log(i18n.te(key)); // false
// Workaround
console.log(i18n.t(key) !== key); // true

Because of the implicit fallback i18n.t will return the en localization for the en-US locale. In my opinion i18n.te should use the same implicit fallback logic as i18n.t, but it does not, resulting in i18n.te('hello') returning false in the example above.

As a workaround, because I know that i18n.t will return the passed key if it does not find any suitable localization, I check if the translation equals its key.

WIStudent avatar Sep 16 '20 09:09 WIStudent

I've implemented something like this by extending the VueI18n class. It only handles the case where you do want it to check the fallback chain, not for when you want the old behavior.

class CustomVueI18n extends VueI18n {
    constructor(props) {
        super(props);
    }

    _te(key, locale, messages, ...args) {
        const chain = this._getLocaleChain(locale, this.fallbackLocale);
        return chain.some((lang) => super._te(key, lang, messages, ...args));
    }
}

0Rick0 avatar Aug 11 '21 08:08 0Rick0

Hello, any update on this? We've solved the issue by extending the VueI18n class ass suggested above but having $te check for any available translation key instead of just one translation key specific to the current locale sounds pretty interesting. Maybe even add an option to include fallback locales in the check or not?

cyp-v avatar Mar 28 '23 07:03 cyp-v