Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add linked message formatting #467

Merged
merged 4 commits into from
Nov 18, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions gitbook/en/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,44 @@ Output the below:
```html
<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'
}
}
}
```

Template the below:

```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>
```

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', () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Some describe('linked translation', () => { lines are consolidated to single one.
I thinkt it is better to describe one concept that has several test cases.

Before

linked translation
 ✔️ should foo
linked translation
 ✔️ should bar
linked translation
 ✔️ should buz

After

linked translation
 ✔️ should foo
 ✔️ should bar
 ✔️ should buz

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