Page MenuHomePhabricator

Allow the usage of i18n plugin with inject
Open, Needs TriagePublicFeature

Description

Feature summary
Allow using the i18n plugin with Vue inject so it can be called from composition API setup() function.

Use case(s) (list the steps that you performed to discover that problem, and describe the actual underlying problem which you want to solve. Do not describe only a solution):

$i18n is only available inside the <template> tag and through the component instance this. This is causing the creation of unnecessary options API methods or computed properties in components written with the composition API to gain access to this.$i18n. While this works it adds extra complexity to the writing and reviewing of Vue code in our software as mentioned in review comments. A common use case is when trying to create a set of translations within a loop:

<span
	v-for="( thing, index ) in someThings"
	:key="index"
>
	{{ $i18n( `some-key-${thing}` ) }}
</span>
const someThings = [ 'thing1', 'thing2' ];
// @vue/component
module.exports = exports ={
  setup() {
    return {
      someThings
    }
  }
}

The rule eslint(mediawiki/no-vue-dynamic-i18n) discourages the creation of the key in the template, hence the only existing alternatives are using Vue options API methods or computed properties. If we allow to inject i18n from setup one could write:

<span
	v-for="( translatedThing, index ) in someTranslatedThings"
	:key="index"
>
	{{ translatedThing }}
</span>
const someThings = [ 'thing1', 'thing2' ];
// @vue/component
module.exports = exports = {
   setup() {
    const i18n = inject( 'i18n' );
    const someTranslatedThings = someThings.map( ( x ) => i18n( `some-key-${thing}` ).text() );
    return {
      someTranslatedThings
    }
  }
}

Benefits (why should this be implemented?):

  • Avoid unnecessary options API methods in composition API code to gain access to this.$i18n and method calls from templates
  • Avoid unnecessary options API computed properties in composition API code to gain access to this.$i18n for translations that do not depend on state changes
  • It aligns with eslint(mediawiki/no-vue-dynamic-i18n) rule

Event Timeline

Change 910562 had a related patch set uploaded (by Sergio Gimeno; author: Sergio Gimeno):

[mediawiki/core@master] Vue: make i18n plugin injectable in Vue 3 setup functions

https://gerrit.wikimedia.org/r/910562

Since $i18n() is just an alias for mw.message(), the documentation currently recommends just using mw.message() for these cases: https://www.mediawiki.org/wiki/Vue.js#Complex_use_cases . $i18n() is really just a workaround for the fact that you can't use globals like mw inside the template.

But I've merged your patch since it doesn't hurt to have it available this way.

Change 910562 merged by jenkins-bot:

[mediawiki/core@master] Vue: make i18n plugin injectable in Vue 3 setup functions

https://gerrit.wikimedia.org/r/910562