Skip to content

Commit

Permalink
feat: how to get locale messages from a given key (#87)
Browse files Browse the repository at this point in the history
* feat: the way to get locale messages from the specified key

* update docs
  • Loading branch information
kazupon authored Aug 7, 2020
1 parent 2dd1d15 commit 7d703eb
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 6 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ See the below examples:
- [Example with using Composable API](https://github.com/intlify/vue-i18n-next/blob/master/examples/composable/components/datetime-format.html)
- [Example with using Legacy API](https://github.com/intlify/vue-i18n-next/blob/master/examples/legacy/components/datetime-format.html)


## :lollipop: Examples

See the [`examples`](https://github.com/intlify/vue-i18n-next/tree/master/examples) directory.
Expand All @@ -79,7 +78,9 @@ The examples are offered that use the following two API styles:

#### APIs
- The return value of `$t` and `t` methods is **string** only. object and array values ​​are no longer returned.
- As an alternative way, you can use `$tm` / `tm`
- The return value of `$tc` and `tc` methods is **string** only. object and array values ​​are no longer returned.
- As an alternative way, you can use `$tm` / `tm`
- `VueI18n` class cannot used with `new`. It can only be used via the `$i18n` property of Vue instance.
- In vue-i18n-next, by replacing `new VueI18n` with `createI18n`, you can use existing `VueI18n` options as they are.
- See the `examples/legacy` directory.
Expand Down Expand Up @@ -191,6 +192,7 @@ yarn add vue-i18n@next
- [x] setPostTranslationHandler
- [x] getMissingHandler
- [x] setMissingHandler
- [x] tm
- Legacy API: compatible supporting
- VueI18n
- [x] locale
Expand Down Expand Up @@ -225,13 +227,15 @@ yarn add vue-i18n@next
- [x] setNumberFormat
- [x] mergeNumberFormat
- [x] getChoiceIndex
- [x] tm
- Inejctted in Vue Prototype API
- [x] $i18n
- [x] $t
- [x] $tc
- [x] $te
- [x] $d
- [x] $n
- [x] $tm
- Component options
- [x] messages
- [x] pluralRule
Expand Down
17 changes: 16 additions & 1 deletion src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
VNodeArrayChildren
} from 'vue'
import { WritableComputedRef, ComputedRef } from '@vue/reactivity'
import { Path, parse as parsePath } from './path'
import { Path, parse as parsePath, resolveValue } from './path'
import {
DateTimeFormats as DateTimeFormatsType,
NumberFormats as NumberFormatsType,
Expand All @@ -34,6 +34,7 @@ import {
} from './message/runtime'
import {
Locale,
LocaleMessageValue,
LocaleMessages,
createRuntimeContext,
RuntimeContext,
Expand Down Expand Up @@ -195,6 +196,7 @@ export interface Composer<
n(value: number, key: string, locale: Locale): string
n(value: number, options: NumberOptions): string
n(...args: unknown[]): string // for internal
tm(key: Path): LocaleMessageValue<Message> | {}
getLocaleMessage(locale: Locale): LocaleMessageDictionary<Message>
setLocaleMessage(
locale: Locale,
Expand Down Expand Up @@ -696,6 +698,18 @@ export function createComposer<
)
}

// tm
function tm(key: Path): LocaleMessageValue<Message> | {} {
const messages = _messages.value[_locale.value] || {}
const target = resolveValue(messages, key)
// prettier-ignore
return target != null
? target as LocaleMessageValue<Message>
: __root
? __root.tm(key) as LocaleMessageValue<Message> || {}
: {}
}

// getLocaleMessage
function getLocaleMessage(locale: Locale): LocaleMessageDictionary<Message> {
return (_messages.value[locale] || {}) as LocaleMessageDictionary<Message>
Expand Down Expand Up @@ -869,6 +883,7 @@ export function createComposer<
t,
d,
n,
tm,
getLocaleMessage,
setLocaleMessage,
mergeLocaleMessage,
Expand Down
9 changes: 8 additions & 1 deletion src/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
LocaleMessages,
LocaleMessageDictionary,
PostTranslationHandler,
FallbackLocale
FallbackLocale,
LocaleMessageValue
} from './core/context'
import { TranslateOptions } from './core/translate'
import {
Expand Down Expand Up @@ -139,6 +140,7 @@ export interface VueI18n<
tc(key: Path, choice: number, named: Record<string, unknown>): TranslateResult
tc(...args: unknown[]): TranslateResult // for $tc
te(key: Path, locale?: Locale): boolean
tm(key: Path): LocaleMessageValue<VueMessageType> | {}
getLocaleMessage(locale: Locale): LocaleMessageDictionary<VueMessageType>
setLocaleMessage(
locale: Locale,
Expand Down Expand Up @@ -510,6 +512,11 @@ export function createVueI18n<
return resolveValue(message, key) !== null
},

// tm
tm(key: Path): LocaleMessageValue<VueMessageType> | {} {
return composer.tm(key)
},

// getLocaleMessage
getLocaleMessage(locale: Locale): LocaleMessageDictionary<VueMessageType> {
return composer.getLocaleMessage(locale)
Expand Down
26 changes: 24 additions & 2 deletions src/mixin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ComponentOptions, getCurrentInstance } from 'vue'
import { Path } from './path'
import { Locale } from './core/context'
import { Composer, ComposerInternalOptions, CustomBlocks } from './composer'
import { Locale, LocaleMessageValue } from './core/context'
import {
Composer,
ComposerInternalOptions,
CustomBlocks,
VueMessageType
} from './composer'
import {
VueI18n,
VueI18nInternal,
Expand Down Expand Up @@ -134,6 +139,20 @@ declare module '@vue/runtime-core' {
* This property is supported for legacy API only
*/
$n?: (...args: unknown[]) => NumberFormatResult
/**
* translation messages method
*
* @param key - required, target keypath
* @returns locale messages
*
* @remarks
* Get the locale message of `key`.
* Get in preferentially component locale messages than global locale messages.
* If the target locale messages is not found locally, get it from the global, otherwise returns an empty object.
*
* This property is supported for legacy API only
*/
$tm?: (key: Path) => LocaleMessageValue<VueMessageType> | {}
}
}

Expand Down Expand Up @@ -206,6 +225,8 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
this.$i18n.d(...args)
this.$n = (...args: unknown[]): NumberFormatResult =>
this.$i18n.n(...args)
this.$tm = (key: Path): LocaleMessageValue<VueMessageType> | {} =>
this.$i18n.tm(key)
},

mounted(): void {
Expand All @@ -226,6 +247,7 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
delete this.$te
delete this.$d
delete this.$n
delete this.$tm

i18n.__deleteInstance(instance)
delete this.$i18n
Expand Down
37 changes: 36 additions & 1 deletion test/composer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
VueMessageType
} from '../src/composer'
import { generateFormatCacheKey } from '../src/utils'
import { watch, nextTick, Text, createVNode } from 'vue'
import { watch, watchEffect, nextTick, Text, createVNode } from 'vue'

describe('locale', () => {
test('default value', () => {
Expand Down Expand Up @@ -670,6 +670,41 @@ describe('n', () => {
})
})

test('tm', async () => {
const composer = createComposer({
locale: 'ja',
messages: {
en: {},
ja: {
foo: {
bar: {
buz: 'hello'
},
codes: {
errors: ['error1', 'error2']
}
}
}
}
})

let messages1 = composer.tm('foo.bar')
let messages2 = composer.tm('foo.codes')
expect(messages1).toEqual({ buz: 'hello' })
expect(messages2).toEqual({ errors: ['error1', 'error2'] })

watchEffect(() => {
messages1 = composer.tm('foo.bar')
messages2 = composer.tm('foo.codes')
})

composer.locale.value = 'en'
await nextTick()

expect(messages1).toEqual({})
expect(messages2).toEqual({})
})

describe('getLocaleMessage / setLocaleMessage / mergeLocaleMessage', () => {
test('basic', () => {
const {
Expand Down
36 changes: 36 additions & 0 deletions test/legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { warn } from '../src/utils'
import { createVueI18n } from '../src/legacy'
import { errorMessages, I18nErrorCodes } from '../src/errors'
import { getWarnMessage, I18nWarnCodes } from '../src/warnings'
import { watchEffect, nextTick } from 'vue'

test('locale', () => {
const i18n = createVueI18n()
Expand Down Expand Up @@ -234,6 +235,41 @@ test('te', () => {
expect(i18n.te('message.hallo', 'ja')).toEqual(false)
})

test('tm', async () => {
const i18n = createVueI18n({
locale: 'ja',
messages: {
en: {},
ja: {
foo: {
bar: {
buz: 'hello'
},
codes: {
errors: ['error1', 'error2']
}
}
}
}
})

let messages1 = i18n.tm('foo.bar')
let messages2 = i18n.tm('foo.codes')
expect(messages1).toEqual({ buz: 'hello' })
expect(messages2).toEqual({ errors: ['error1', 'error2'] })

watchEffect(() => {
messages1 = i18n.tm('foo.bar')
messages2 = i18n.tm('foo.codes')
})

i18n.locale = 'en'
await nextTick()

expect(messages1).toEqual({})
expect(messages2).toEqual({})
})

test('getLocaleMessage / setLocaleMessage / mergeLocaleMessage', () => {
const i18n = createVueI18n({
messages: {
Expand Down

0 comments on commit 7d703eb

Please sign in to comment.