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

Global replacements as default value for named formatting

Open ThaDaVos opened this issue 4 years ago • 6 comments

At current state one can define formatting with replacements as shown here in the docs: https://kazupon.github.io/vue-i18n/guide/formatting.html#named-formatting <p>{{ $t('welcome', { user: { name: 'John Doe' } }) }}</p>

The above is really useful but what if you have a certain replacement on many of your translations keys? You'll have to find a way to get that variable everywhere you have a translation key which needs it.

So I want to propose the following: Global Replacements In this way, you will only have to define it once. Also it should be locally overridable as show below.

Why I need this? Simple, I don't want to repeat myself and make mistakes later on when a replacement needs to be renamed or something.

Setup

const i18n = new VueI18n({
  locale: 'en-US',
  messages: {
    'en-US': {
      'welcome': 'Welcome {user.name}'
    },
    // ...
  },
  replacements: {
    user: {
      name: "John Doe"
    }
  }
})

Input

<p>$t('welcome')</p>
<!-- Local override -->
<p>$t('welcome', { user: { name: 'Jane Doe' } })</p>

Output:

<p>Hello John Doe</p>
<!-- Local override -->
<p>Hello Jane Doe</p>

ThaDaVos avatar Jul 01 '20 08:07 ThaDaVos

At the current state I'll hack it in locally by overriding the $t function to have a default object as second parameter

ThaDaVos avatar Jul 01 '20 08:07 ThaDaVos

I can imagine that it could be painful if one need to pass same argument to so many messages. Could you give more specific use case ? I think it is unlikely to pass same user name in so many places.

exoego avatar Jul 01 '20 09:07 exoego

The username was just an example, but the application I'm be working on it will be a company name, which will be repeated a lot through all the main texts on the website.

Simply said I think it will be really useful to have a global replacements object as there are more use cases out their

ThaDaVos avatar Jul 01 '20 12:07 ThaDaVos

I've patched it as follows, for anyone trying the same:

const originalTranslate = VueI18n.prototype._translate;
VueI18n.prototype._translate = function (
    messages,
    locale,
    fallback,
    key,
    host,
    interpolateMode,
    args) {

    if (!args) args = {};
    // Custom global replacements, I prefixed them with `const` as these are constants, also used : instead of . as it doesn't work otherwise
    args['const:sitename'] = "Bedrijf X";
    args['const:sitecity'] = "Dorpje";

    return originalTranslate.apply(this, [messages, locale, fallback, key, host, interpolateMode, args ]);
};

Above needs to be done before calling Vue.install - I did it right after the import

ThaDaVos avatar Jul 02 '20 11:07 ThaDaVos

+1 on this one, global keys, for named keys that you use over and over again, like in his extremely good example, a company name, would be useful!

fjeddy avatar Oct 25 '20 21:10 fjeddy

+1

lucassimines avatar Mar 14 '23 20:03 lucassimines