kazupon / vue-i18n

:globe_with_meridians: Internationalization plugin for Vue.js
https://kazupon.github.io/vue-i18n/
MIT License
7.27k stars 861 forks source link

Using custom formatting breaks interpolation #1087

Open Pochwar opened 3 years ago

Pochwar commented 3 years ago

vue & vue-i18n version

vue: 2.6.11 - vue-i18n: 8.18.2

Issue

Using a custom formatter breaks the functionality of component interpolation.

Following the docs example of component interpolation (https://kazupon.github.io/vue-i18n/guide/interpolation.html#basic-usage), I got this output: <label for="tos">I accept xxx <a href="url" target="_blank">Term of Service</a>.</label>

But if I add a custom formatter like in the docs (https://kazupon.github.io/vue-i18n/guide/formatting.html#custom-formatting), I got this output: <label for="tos">I accept xxx [object Object].</label>

aguidis commented 2 years ago

Hello @Pochwar Do you have any update on this issue ?

mediafreakch commented 2 years ago

For anyone else ending up here: I got the component interpolation to work by changing the custom formatter like this:

+ import MessageFormat from '@messageformat/core'
- import MessageFormat from 'messageformat'

export default class CustomFormatter {
constructor (options = {}) {
    this._locale = options.locale || 'en-US'
-   this._formatter = new MessageFormat(this._locale)
+   this._formatter = new MessageFormat(this.locale, { returnType: 'values' })
    this._caches = Object.create(null)
  }

  interpolate (message, values) {
    let fn = this._caches[message]
    if (!fn) {
-      fn = this._formatter.compile(message, this._locale)
+      fn = this._formatter.compile(message)
      this._caches[message] = fn
    }
-    return [fn(values)]
+   return fn(values)
  }
}
mediafreakch commented 2 years ago

The actual solution is a bit more complicated, but actually there's a complete example here, which involves some more logic around returning the values.