kazupon / vue-i18n

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

Adding `scope` option to translations #426

Open SzNagyMisu opened 6 years ago

SzNagyMisu commented 6 years ago

Issuehunt badges

Feature request

I would like to be able to do the following in components:

this.$t('message.path', { scope: 'my.very.long.scope.to.the.message' })
// or
const myScope = 'my.very.long.scope.to.the.message'
this.$t('message.path', { scope: myScope })

or even better:

const MyComponent = {
  template: `<p v-t="'message.path'"></p>`,
  i18n: { scope: myScope }
}

So basically, my goal would be to have my locale messages in one place and provide a socpe for a component, so that I can type less when translating lots of deeply nested messages.

All I can do now is:

const MyComponent = {
  template: `<p v-t="myScope + '.message.path'"></p>`,
  data () {
    return { myScope = '...' }
  },
  // and
  methods: {
    translateMessage (message) { return this.$t(`${this.myScope}.${message}`) }
  }
}

But having a scope option for components would be more elegant (or, at least, less cumbersome...). Of course, the fallback logic should be considered too.

@kazupon what do you think?

Also, I would be more than happy to try and provide a PR for the feature.


IssueHunt Summary ### Backers (Total: $15.00) - [0maxxam0 0maxxam0](https://issuehunt.io/u/0maxxam0) ($10.00) - [varna varna](https://issuehunt.io/u/varna) ($5.00) #### [Become a backer now!](https://issuehunt.io/r/kazupon/vue-i18n/issues/426) #### [Or submit a pull request to get the deposits!](https://issuehunt.io/r/kazupon/vue-i18n/issues/426) ### Tips - Checkout the [Issuehunt explorer](https://issuehunt.io/r/kazupon/vue-i18n/) to discover more funded issues. - Need some help from other developers? [Add your repositories](https://issuehunt.io/r/new) on IssueHunt to raise funds.
kazupon commented 5 years ago

Hmm 🤔, Certainly it maybe useful to support it.

Typically, As a sign that the path becomes longer, I think that we can not be managing the locale messages well. When the locale messages gets bloated, I recommend using SFC i18n custom block. As a result, the path will be simple, due to you can manage locale messages on a component units

SzNagyMisu commented 5 years ago

@kazupon I think there is truth in what you say, so I will just try and use SFC I18n custom block whereever it is possible. Thanks for the idea!

Should I close the issue?

vansteki commented 5 years ago

+1 for scope option SFC i18n custom block is good. But I think the scope is also a helpful and practical feature.

Bosee commented 5 years ago

+1 for scope option very useful for large project

bponomarenko commented 5 years ago

it is possible to achieve the same result with built-in filters, which will syntax nicer:


const scoped = key => 'root.scope.' + key;

const MyComponent = {
  filters { scoped: scoped },
  template: `<p v-t="'.message.path' | scoped"></p>`,
  methods: {
    translateMessage (key) { return this.$t(scoped(key)) }
  }
}
IssueHuntBot commented 5 years ago

@0maxxam0 has funded $10.00 to this issue.


Nettsentrisk commented 5 years ago

This seems to be a parallel to the namespaces option in the vue-i18next library or the keyPrefix option.

When you're building a large application, or a web site, you will typically want to split up your translations into namespaces/groups/sectors. The key paths would then reflect this.

However, let's say you want to use translations in a component, but you only want to use translations from a certain namespace in that component. Having to write out the entire path is cumbersome.

So if you set a namespace/scope/prefix option on the i18n options for a component, then you will be instructing $t() etc. to prepend/use the namespace/scope/prefix to all calls to $t() within that component.

So instead of $t('components.componentName.level1.level2') you could have $t('level1.level2') by setting the namespace/scope/prefix to components.componentName.

paulgeisler commented 4 years ago

How is this feature coming along?

matthew-white commented 4 years ago

I work on a project with volunteer translators who contribute using Transifex. We're adding internationalization to a Vue project now, and I think our workflow will be similar to the one that Vue CLI uses for Transifex: en.json is imported to Transifex as it changes, then Transifex exports a JSON file for each locale.

With this workflow, I think it'd be difficult to use SFC i18n custom blocks. However, it's a fairly large project, so paths can also get fairly long.

I think being able to add a scope option to a component would be very helpful. I also think it'd be helpful for components to be able to access paths outside the scope in case they need to mix scoped messages with more general messages. (For example, a component that mostly only needs messages under a specific path might also need to access the localized app name.) Maybe it could work in a similar way as fallbackRoot?

varna commented 4 years ago

I started using i18next a year ago because of namespaces feature. Still regularly checking progress here.

issuehunt-oss[bot] commented 4 years ago

@varna has funded $5.00 to this issue.


geauser commented 2 years ago

Any updates on this feature request?

kuba-lilz commented 1 year ago

When the locale messages gets bloated, I recommend using SFC i18n custom block.

Perhaps I'm not seeing an obvious workaround, but using SFC i18n custom block means that the only practical way to manage translations is to let translators access whole code repository, work directly inside source code and require them to use version control tools. Something businesses might not be happy doing when outsourcing translations, and many translators wouldn't be comfortable with due to technical barrier.

Is there a way to at least import content into SFC i18n custom blocks? Something conceptually similar to:

<script>
import englishTextData from "~/languages/english.yaml" ;
import japaneseTextData from "~/languages/japanese.yaml" ;
</script>

<i18n>
{
  "english": englishTextData.pageA.componentB,
  "japanese": japaneseTextData.pageA.componentB
}
</i18n>

which of course doesn't even compile.

On a side note - I would take an exception with automatically proclaiming large translation files as bloated without examining the project.

xmcx3 commented 1 year ago
const genNS = (ns: stirng) => ((key: string) => `${ns}.${key}`)

const ns = genNS('hello.world')

this.$t(ns`path`)
FabianMontoya commented 8 months ago

How is this feature coming along? It should be a must of this library