summaryrefslogtreecommitdiff
path: root/doc/development/i18n/externalization.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/i18n/externalization.md')
-rw-r--r--doc/development/i18n/externalization.md128
1 files changed, 73 insertions, 55 deletions
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 796a1f44ccd..53825f0904a 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -131,40 +131,70 @@ You can mark that content for translation with:
### JavaScript files
-In JavaScript we added the `__()` (double underscore parenthesis) function that
-you can import from the `~/locale` file. For instance:
+The `~/locale` module exports the following key functions for externalization:
+
+- `__()` (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
-import { __ } from '~/locale';
+import { __, s__, n__ } from '~/locale';
+
+const defaultErrorMessage = s__('Branches|Create branch failed.');
const label = __('Subscribe');
+const message = n__('Apple', 'Apples', 3)
```
-To test JavaScript translations you must:
-
-- 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`.
+To test JavaScript translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
### 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.
-For example:
+This means you can externalize strings in Vue templates without having to import these functions from the `~/locale` file:
-```javascript
-import { __, s__ } from '~/locale';
-const label = __('Subscribe');
-const nameSpacedlabel = __('Plan|Subscribe');
+```html
+<template>
+ <h1>{{ s__('Branches|Create a new branch') }}</h1>
+ <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
└───alert_settings
@@ -179,60 +209,41 @@ For the static text strings we suggest two patterns for using these translations
/* Integration constants */
- export const I18N_ALERT_SETTINGS_FORM = {
- saveBtnLabel: __('Save changes'),
- };
+ export const MSG_ALERT_SETTINGS_FORM_ERROR = __('Failed to save alert settings.')
// alert_settings_form.vue
import {
- I18N_ALERT_SETTINGS_FORM,
+ MSG_ALERT_SETTINGS_FORM_ERROR,
} from '../constants';
<script>
export default {
- i18n: {
- I18N_ALERT_SETTINGS_FORM,
- }
+ MSG_ALERT_SETTINGS_FROM_ERROR,
}
</script>
<template>
- <gl-button
- ref="submitBtn"
- variant="success"
- type="submit"
- >
- {{ $options.i18n.I18N_ALERT_SETTINGS_FORM }}
- </gl-button>
+ <gl-alert v-if="showAlert">
+ {{ $options.MSG_ALERT_SETTINGS_FORM_ERROR }}
+ </gl-alert>
</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
- <script>
- export default {
- i18n: {
- buttonLabel: s__('Plan|Button Label')
- }
- },
- </script>
+Using either `constants` or `$options.i18n` allows us to reference messages directly in specs:
- <template>
- <gl-button :aria-label="$options.i18n.buttonLabel">
- {{ $options.i18n.buttonLabel }}
- </gl-button>
- </template>
- ```
+```javascript
+import { MSG_ALERT_SETTINGS_FORM_ERROR } from 'path/to/constants.js';
-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.
-1. Generate JSON files using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`.
+// better
+expect(wrapper.text()).toEqual(MyComponent.i18n.buttonLabel);
+// also better
+expect(wrapper.text()).toEqual(MSG_ALERT_SETTINGS_FORM_ERROR);
+```
### Dynamic translations
@@ -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 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`.