Skip to content

Commit

Permalink
⭐ new(index): Add linked message formatting (#467) by @exoego
Browse files Browse the repository at this point in the history
* Add converters to link key interpolation.

* Add document for linked key formatting

* Add test for unknown link key modifier
  • Loading branch information
TATSUNO Yasuhiro authored and kazupon committed Nov 18, 2018
1 parent fabc563 commit 776b81b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 13 deletions.
39 changes: 38 additions & 1 deletion gitbook/en/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,43 @@ Output the below:
<p>DIO: the world !!!!</p>
```

### Formatting linked locale messages

If the language distinguish cases of character, you may need control the case of the linked locale messages.
Linked messages can be formatted with modifier `@.MODIFIER:key`

The below modifiers are available currently.

* `upper`: Uppercase all characters in the linked message.
* `lower`: Lowercase all characters in the linked message.

Locale messages the below:

```javascript
const messages = {
en: {
message: {
homeAddress: 'Home address',
missingHomeAddress: 'Please provide @.lower:message.homeAddress'
}
}
}
```

```html
<label>{{ $t('message.missingHomeAddress') }}</label>

<p class="error">{{ $t('message.missingHomeAddress') }}</p>
```

Output the below:

```html
<label>Home address</label>

<p class="error">Please provide home address</p>
```

### Grouping by brackets

A translation key of linked locale message can also have the form of `@:(message.foo.bar.baz)` in which the link to another translation key is within brackets `()`.
Expand Down Expand Up @@ -132,4 +169,4 @@ Output the below:

```html
<p>There's a reason, you lost, DIO.</p>
```
```
19 changes: 15 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ const numberFormatKeys = [
'localeMatcher',
'formatMatcher'
]
const linkKeyMatcher = /(?:@:(?:[\w\-_|.]+|\([\w\-_|.]+\)))/g
const linkKeyMatcher = /(?:@(?:\.[a-z]+)?:(?:[\w\-_|.]+|\([\w\-_|.]+\)))/g
const linkKeyPrefixMatcher = /^@(?:\.([a-z]+))?:/
const bracketsMatcher = /[()]/g
const formatters = {
'upper': (str) => str.toLocaleUpperCase(),
'lower': (str) => str.toLocaleLowerCase()
}

export default class VueI18n {
static install: () => void
Expand Down Expand Up @@ -234,7 +239,7 @@ export default class VueI18n {
}

// Check for the existence of links within the translated string
if (ret.indexOf('@:') >= 0) {
if (ret.indexOf('@:') >= 0 || ret.indexOf('@.') >= 0) {
ret = this._link(locale, message, ret, host, interpolateMode, values, visitedLinkStack)
}

Expand Down Expand Up @@ -263,8 +268,11 @@ export default class VueI18n {
continue
}
const link: string = matches[idx]
// Remove the leading @: and the brackets
const linkPlaceholder: string = link.substr(2).replace(bracketsMatcher, '')
const linkKeyPrefixMatches: any = link.match(linkKeyPrefixMatcher)
const [linkPrefix, formatterName] = linkKeyPrefixMatches

// Remove the leading @:, @.case: and the brackets
const linkPlaceholder: string = link.replace(linkPrefix, '').replace(bracketsMatcher, '')

if (visitedLinkStack.includes(linkPlaceholder)) {
if (process.env.NODE_ENV !== 'production') {
Expand Down Expand Up @@ -298,6 +306,9 @@ export default class VueI18n {
locale, linkPlaceholder, translated, host,
Array.isArray(values) ? values : [values]
)
if (formatters.hasOwnProperty(formatterName)) {
translated = formatters[formatterName](translated)
}

visitedLinkStack.pop()

Expand Down
20 changes: 12 additions & 8 deletions test/unit/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,34 @@ describe('basic', () => {
it('should translate simple link', () => {
assert.equal(i18n.t('message.link'), messages.en.message.hello)
})
})

describe('linked translation', () => {
it('should translate link at the end of locale', () => {
assert.equal(i18n.t('message.linkEnd'), 'This is a linked translation to the world')
})
})

describe('linked translation', () => {
it('should translate link within a locale', () => {
assert.equal(i18n.t('message.linkWithin'), 'Isn\'t the world we live in great?')
})
})

describe('linked translation', () => {
it('should translate multiple links within a locale', () => {
assert.equal(i18n.t('message.linkMultiple'), 'Hello hoge!, isn\'t the world great?')
})
})

describe('linked translation', () => {
it('should translate link with braces ', () => {
assert.strictEqual(i18n.t('message.linkBrackets'), 'Hello hoge. Isn\'t the world great?')
})

it('should translate link with lower-case formatting', () => {
assert.strictEqual(i18n.t('message.linkCaseLower'), 'Please provide home address')
})

it('should translate link with upper-case formatting', () => {
assert.strictEqual(i18n.t('message.linkCaseUpper'), 'HOME ADDRESS')
})

it('should translate link without formatting if modifier is not known.', () => {
assert.strictEqual(i18n.t('message.linkCaseUnknown'), 'Home address')
})
})

describe('ja locale', () => {
Expand Down
4 changes: 4 additions & 0 deletions test/unit/fixture/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export default {
linkHyphen: '@:hyphen-hello',
linkUnderscore: '@:underscore_hello',
linkList: '@:message.hello: {0} {1}',
linkCaseLower: 'Please provide @.lower:message.homeAddress',
linkCaseUpper: '@.upper:message.homeAddress',
linkCaseUnknown: '@.unknown:message.homeAddress',
homeAddress: 'Home address',
circular1: 'Foo @:message.circular2',
circular2: 'Bar @:message.circular3',
circular3: 'Buz @:message.circular1',
Expand Down

0 comments on commit 776b81b

Please sign in to comment.