Commit f9c40af4 authored by Tom Quirk's avatar Tom Quirk Committed by Russell Dickenson

Expand i18n guidelines for Vue/frontend

parent 9474c9a4
...@@ -131,40 +131,70 @@ You can mark that content for translation with: ...@@ -131,40 +131,70 @@ You can mark that content for translation with:
### JavaScript files ### JavaScript files
In JavaScript we added the `__()` (double underscore parenthesis) function that The `~/locale` module exports the following key functions for externalization:
you can import from the `~/locale` file. For instance:
- `__()` (double underscore parenthesis)
- `s__()` (namespaced double underscore parenthesis)
- `__()` Mark content for translation (note the double underscore).
- `s__()` Mark namespaced content for translation
- `n__()` Mark pluralized content for translation
```javascript ```javascript
import { __ } from '~/locale'; import { __, s__, n__ } from '~/locale';
const defaultErrorMessage = s__('Branches|Create branch failed.');
const label = __('Subscribe'); const label = __('Subscribe');
const message = n__('Apple', 'Apples', 3)
``` ```
To test JavaScript translations you must: To test JavaScript translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
- Change the GitLab localization to a language other than English.
- Generate JSON files by using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`.
### Vue files ### Vue files
In Vue files, we make the following functions available: In Vue files, we make the following functions available to Vue templates using the `translate` mixin:
- `__()` (double underscore parenthesis) - `__()`
- `s__()` (namespaced double underscore parenthesis) - `s__()`
- `n__()`
- `sprintf`
You can therefore import from the `~/locale` file. This means you can externalize strings in Vue templates without having to import these functions from the `~/locale` file:
For example:
```javascript ```html
import { __, s__ } from '~/locale'; <template>
const label = __('Subscribe'); <h1>{{ s__('Branches|Create a new branch') }}</h1>
const nameSpacedlabel = __('Plan|Subscribe'); <gl-button>{{ __('Create branch') }}</gl-button>
</template>
``` ```
For the static text strings we suggest two patterns for using these translations in Vue files: If you need to translate strings in the Vue component's JavaScript, you can import the necessary externalization function from the `~/locale` file as described in the [JavaScript files](#javascript-files) section.
- External constants file: To test Vue translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
```javascript #### Recommendations
If strings are reused throughout a component, it can be useful to define these strings as variables. We recommend defining an `i18n` property on the component's `$options` object. If there is a mixture of many-use and single-use strings in the component, consider using this approach to create a local [Single Source of Truth](https://about.gitlab.com/handbook/values/#single-source-of-truth) for externalized strings.
```javascript
<script>
export default {
i18n: {
buttonLabel: s__('Plan|Button Label')
}
},
</script>
<template>
<gl-button :aria-label="$options.i18n.buttonLabel">
{{ $options.i18n.buttonLabel }}
</gl-button>
</template>
```
Also consider defining these strings in a `constants.js` file, especially if they need
to be shared across different modules.
```javascript
javascripts javascripts
└───alert_settings └───alert_settings
...@@ -179,60 +209,41 @@ For the static text strings we suggest two patterns for using these translations ...@@ -179,60 +209,41 @@ For the static text strings we suggest two patterns for using these translations
/* Integration constants */ /* Integration constants */
export const I18N_ALERT_SETTINGS_FORM = { export const MSG_ALERT_SETTINGS_FORM_ERROR = __('Failed to save alert settings.')
saveBtnLabel: __('Save changes'),
};
// alert_settings_form.vue // alert_settings_form.vue
import { import {
I18N_ALERT_SETTINGS_FORM, MSG_ALERT_SETTINGS_FORM_ERROR,
} from '../constants'; } from '../constants';
<script> <script>
export default { export default {
i18n: { MSG_ALERT_SETTINGS_FROM_ERROR,
I18N_ALERT_SETTINGS_FORM,
}
} }
</script> </script>
<template> <template>
<gl-button <gl-alert v-if="showAlert">
ref="submitBtn" {{ $options.MSG_ALERT_SETTINGS_FORM_ERROR }}
variant="success" </gl-alert>
type="submit"
>
{{ $options.i18n.I18N_ALERT_SETTINGS_FORM }}
</gl-button>
</template> </template>
``` ```
When possible, you should opt for this pattern, as this allows you to import these strings directly into your component specs for re-use during testing.
- Internal component `$options` object:
```javascript Using either `constants` or `$options.i18n` allows us to reference messages directly in specs:
<script>
export default {
i18n: {
buttonLabel: s__('Plan|Button Label')
}
},
</script>
<template> ```javascript
<gl-button :aria-label="$options.i18n.buttonLabel"> import { MSG_ALERT_SETTINGS_FORM_ERROR } from 'path/to/constants.js';
{{ $options.i18n.buttonLabel }}
</gl-button>
</template>
```
To visually test the Vue translations: // okay
expect(wrapper.text()).toEqual('this test will fail just from button text changing!');
1. Change the GitLab localization to another language than English. // better
1. Generate JSON files using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`. expect(wrapper.text()).toEqual(MyComponent.i18n.buttonLabel);
// also better
expect(wrapper.text()).toEqual(MSG_ALERT_SETTINGS_FORM_ERROR);
```
### Dynamic translations ### Dynamic translations
...@@ -853,3 +864,10 @@ Suppose you want to add translations for a new language, for example, French: ...@@ -853,3 +864,10 @@ Suppose you want to add translations for a new language, for example, French:
git add locale/fr/ app/assets/javascripts/locale/fr/ git add locale/fr/ app/assets/javascripts/locale/fr/
git commit -m "Add French translations for Value Stream Analytics page" git commit -m "Add French translations for Value Stream Analytics page"
``` ```
## Manually test translations from the UI
To manually test Vue translations:
1. Change the GitLab localization to another language than English.
1. Generate JSON files using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment