Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 21:25:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 21:25:58 +0300
commita5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (patch)
treefb69158581673816a8cd895f9d352dcb3c678b1e /doc/development/i18n
parentd16b2e8639e99961de6ddc93909f3bb5c1445ba1 (diff)
Add latest changes from gitlab-org/gitlab@14-0-stable-eev14.0.0-rc42
Diffstat (limited to 'doc/development/i18n')
-rw-r--r--doc/development/i18n/externalization.md330
-rw-r--r--doc/development/i18n/index.md53
-rw-r--r--doc/development/i18n/merging_translations.md53
-rw-r--r--doc/development/i18n/proofreader.md49
-rw-r--r--doc/development/i18n/translation.md104
5 files changed, 288 insertions, 301 deletions
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index b177a7e0138..7ea8378b6db 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -10,16 +10,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
For working with internationalization (i18n),
[GNU gettext](https://www.gnu.org/software/gettext/) is used given it's the most
-used tool for this task and there are a lot of applications that help us
-work with it.
+used tool for this task and there are many applications that help us work with it.
NOTE:
-All `rake` commands described on this page must be run on a GitLab instance, usually GDK.
+All `rake` commands described on this page must be run on a GitLab instance. This instance is
+usually the GitLab Development Kit (GDK).
-## Setting up GitLab Development Kit (GDK)
+## Setting up the GitLab Development Kit (GDK)
-In order to be able to work on the [GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss)
-project you must download and configure it through [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/set-up-gdk.md).
+To work on the [GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss)
+project, you must download and configure it through the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/set-up-gdk.md).
After you have the GitLab project ready, you can start working on the translation.
@@ -27,34 +27,33 @@ After you have the GitLab project ready, you can start working on the translatio
The following tools are used:
-1. [`gettext_i18n_rails`](https://github.com/grosser/gettext_i18n_rails): this
- gem allow us to translate content from models, views and controllers. Also
- it gives us access to the following Rake tasks:
- - `rake gettext:find`: Parses almost all the files from the
- Rails application looking for content that has been marked for
- translation. Finally, it updates the PO files with the new content that
- it has found.
- - `rake gettext:pack`: Processes the PO files and generates the
- MO files that are binary and are finally used by the application.
-
-1. [`gettext_i18n_rails_js`](https://github.com/webhippie/gettext_i18n_rails_js):
- this gem is useful to make the translations available in JavaScript. It
- provides the following Rake task:
- - `rake gettext:po_to_json`: Reads the contents from the PO files and
- generates JSON files containing all the available translations.
-
-1. PO editor: there are multiple applications that can help us to work with PO
- files, a good option is [Poedit](https://poedit.net/download) which is
- available for macOS, GNU/Linux and Windows.
+- [`gettext_i18n_rails`](https://github.com/grosser/gettext_i18n_rails):
+ this gem allows us to translate content from models, views, and controllers. It also gives us
+ access to the following Rake tasks:
+
+ - `rake gettext:find`: parses almost all the files from the Rails application looking for content
+ marked for translation. It then updates the PO files with this content.
+ - `rake gettext:pack`: processes the PO files and generates the binary MO files that the
+ application uses.
+
+- [`gettext_i18n_rails_js`](https://github.com/webhippie/gettext_i18n_rails_js):
+ this gem makes the translations available in JavaScript. It provides the following Rake task:
+
+ - `rake gettext:po_to_json`: reads the contents of the PO files and generates JSON files that
+ contain all the available translations.
+
+- PO editor: there are multiple applications that can help us work with PO files. A good option is
+ [Poedit](https://poedit.net/download),
+ which is available for macOS, GNU/Linux, and Windows.
## Preparing a page for translation
-We basically have 4 types of files:
+There are four file types:
-1. Ruby files: basically Models and Controllers.
-1. HAML files: these are the view files.
-1. ERB files: used for email templates.
-1. JavaScript files: we mostly need to work with Vue templates.
+- Ruby files: models and controllers.
+- HAML files: view files.
+- ERB files: used for email templates.
+- JavaScript files: we mostly work with Vue templates.
### Ruby files
@@ -72,7 +71,7 @@ Or:
hello = "Hello world!"
```
-You can easily mark that content for translation with:
+You can mark that content for translation with:
```ruby
def hello
@@ -86,26 +85,21 @@ Or:
hello = _("Hello world!")
```
-Be careful when translating strings at the class or module level since these would only be
-evaluated once at class load time.
-
-For example:
+Be careful when translating strings at the class or module level since these are only evaluated once
+at class load time. For example:
```ruby
validates :group_id, uniqueness: { scope: [:project_id], message: _("already shared with this group") }
```
-This would be translated when the class is loaded and result in the error message
-always being in the default locale.
-
-Active Record's `:message` option accepts a `Proc`, so we can do this instead:
+This is translated when the class loads and results in the error message always being in the default
+locale. Active Record's `:message` option accepts a `Proc`, so do this instead:
```ruby
validates :group_id, uniqueness: { scope: [:project_id], message: -> (object, data) { _("already shared with this group") } }
```
-Messages in the API (`lib/api/` or `app/graphql`) do
-not need to be externalized.
+Messages in the API (`lib/api/` or `app/graphql`) do not need to be externalized.
### HAML files
@@ -145,13 +139,20 @@ import { __ } from '~/locale';
const label = __('Subscribe');
```
-In order to test JavaScript translations you have to change the GitLab
-localization to another language than English and you have to generate JSON files
-using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`.
+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`.
### Vue files
-In Vue files we make both the `__()` (double underscore parenthesis) function and the `s__()` (namespaced double underscore parenthesis) function available that you can import from the `~/locale` file. For instance:
+In Vue files, we make the following functions available:
+
+- `__()` (double underscore parenthesis)
+- `s__()` (namespaced double underscore parenthesis)
+
+You can therefore import from the `~/locale` file.
+For example:
```javascript
import { __, s__ } from '~/locale';
@@ -228,24 +229,24 @@ For the static text strings we suggest two patterns for using these translations
</template>
```
-In order to visually test the Vue translations you have to change the GitLab
-localization to another language than English and you have to generate JSON files
-using `bin/rake gettext:po_to_json` or `bin/rake gettext:compile`.
+To visually test the Vue translations:
-### Dynamic 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`.
-Sometimes there are some dynamic translations that can't be found by the
-parser when running `bin/rake gettext:find`. For these scenarios you can
-use the [`N_` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind).
+### Dynamic translations
-There is also and alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a).
+Sometimes there are dynamic translations that the parser can't find when running
+`bin/rake gettext:find`. For these scenarios you can use the [`N_` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind).
+There's also an alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a).
## Working with special content
### Interpolation
-Placeholders in translated text should match the code style of the respective source file.
-For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make sure to [avoid splitting sentences when adding links](#avoid-splitting-sentences-when-adding-links).
+Placeholders in translated text should match the respective source file's code style. For example
+use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make sure to
+[avoid splitting sentences when adding links](#avoid-splitting-sentences-when-adding-links).
- In Ruby/HAML:
@@ -257,9 +258,9 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
Use the [`GlSprintf`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/docs/utilities-sprintf--sentence-with-link) component if:
- - you need to include child components in the translation string.
- - you need to include HTML in your translation string.
- - you are using `sprintf` and need to pass `false` as the third argument to
+ - You need to include child components in the translation string.
+ - You need to include HTML in your translation string.
+ - You're using `sprintf` and need to pass `false` as the third argument to
prevent it from escaping placeholder values.
For example:
@@ -272,7 +273,7 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
</gl-sprintf>
```
- In other cases it may be simpler to use `sprintf`, perhaps in a computed
+ In other cases, it might be simpler to use `sprintf`, perhaps in a computed
property. For example:
```html
@@ -344,7 +345,8 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
# => When size == 2: 'There are 2 mice.'
```
- Avoid using `%d` or count variables in singular strings. This allows more natural translation in some languages.
+ Avoid using `%d` or count variables in singular strings. This allows more natural translation in
+ some languages.
- In JavaScript:
@@ -363,13 +365,12 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
The `n_` method should only be used to fetch pluralized translations of the same
string, not to control the logic of showing different strings for different
-quantities. Some languages have different quantities of target plural forms -
-Chinese (simplified), for example, has only one target plural form in our
-translation tool. This means the translator would have to choose to translate
-only one of the strings and the translation would not behave as intended in the
-other case.
+quantities. Some languages have different quantities of target plural forms.
+For example, Chinese (simplified) has only one target plural form in our
+translation tool. This means the translator has to choose to translate only one
+of the strings, and the translation doesn't behave as intended in the other case.
-For example, prefer to use:
+For example, use this:
```ruby
if selected_projects.one?
@@ -379,7 +380,7 @@ else
end
```
-rather than:
+Instead of this:
```ruby
# incorrect usage example
@@ -388,21 +389,22 @@ n_("%{project_name}", "%d projects selected", count) % { project_name: 'GitLab'
### Namespaces
-A namespace is a way to group translations that belong together. They provide context to our translators by adding a prefix followed by the bar symbol (`|`). For example:
+A namespace is a way to group translations that belong together. They provide context to our
+translators by adding a prefix followed by the bar symbol (`|`). For example:
```ruby
'Namespace|Translated string'
```
-A namespace provide the following benefits:
+A namespace:
-- It addresses ambiguity in words, for example: `Promotions|Promote` vs `Epic|Promote`
-- It allows translators to focus on translating externalized strings that belong to the same product area rather than arbitrary ones.
-- It gives a linguistic context to help the translator.
+- Addresses ambiguity in words. For example: `Promotions|Promote` vs `Epic|Promote`.
+- Allows translators to focus on translating externalized strings that belong to the same product
+ area, rather than arbitrary ones.
+- Gives a linguistic context to help the translator.
-In some cases, namespaces don't make sense, for example,
-for ubiquitous UI words and phrases such as "Cancel" or phrases like "Save changes" a namespace could
-be counterproductive.
+In some cases, namespaces don't make sense. For example, for ubiquitous UI words and phrases such as
+"Cancel" or phrases like "Save changes," a namespace could be counterproductive.
Namespaces should be PascalCase.
@@ -412,7 +414,7 @@ Namespaces should be PascalCase.
s_('OpenedNDaysAgo|Opened')
```
- In case the translation is not found it returns `Opened`.
+ If the translation isn't found, `Opened` is returned.
- In JavaScript:
@@ -420,18 +422,19 @@ Namespaces should be PascalCase.
s__('OpenedNDaysAgo|Opened')
```
-The namespace should be removed from the translation. See the
-[translation guidelines for more details](translation.md#namespaced-strings).
+The namespace should be removed from the translation. For more details, see the
+[translation guidelines](translation.md#namespaced-strings).
### HTML
-We no longer include HTML directly in the strings that are submitted for translation. This is for a couple of reasons:
+We no longer include HTML directly in the strings that are submitted for translation. This is
+because:
-1. It introduces a chance for the translated string to accidentally include invalid HTML.
-1. It introduces a security risk where translated strings become an attack vector for XSS, as noted by the
+1. The translated string can accidentally include invalid HTML.
+1. Translated strings can become an attack vector for XSS, as noted by the
[Open Web Application Security Project (OWASP)](https://owasp.org/www-community/attacks/xss/).
-To include formatting in the translated string, we can do the following:
+To include formatting in the translated string, you can do the following:
- In Ruby/HAML:
@@ -449,18 +452,18 @@ To include formatting in the translated string, we can do the following:
// => 'Some <strong>bold</strong> text.'
```
-- In Vue
+- In Vue:
See the section on [interpolation](#interpolation).
-When [this translation helper issue](https://gitlab.com/gitlab-org/gitlab/-/issues/217935) is complete, we plan to update the
-process of including formatting in translated strings.
+When [this translation helper issue](https://gitlab.com/gitlab-org/gitlab/-/issues/217935)
+is complete, we plan to update the process of including formatting in translated strings.
#### Including Angle Brackets
-If a string contains angles brackets (`<`/`>`) that are not used for HTML, it is still flagged by the
-`rake gettext:lint` linter.
-To avoid this error, use the applicable HTML entity code (`&lt;` or `&gt;`) instead:
+If a string contains angle brackets (`<`/`>`) that are not used for HTML, the `rake gettext:lint`
+linter still flags it. To avoid this error, use the applicable HTML entity code (`&lt;` or `&gt;`)
+instead:
- In Ruby/HAML:
@@ -493,12 +496,12 @@ To avoid this error, use the applicable HTML entity code (`&lt;` or `&gt;`) inst
### Numbers
-Different locales may use different number formats. To support localization of numbers, we use `formatNumber`,
-which leverages [`toLocaleString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString).
+Different locales may use different number formats. To support localization of numbers, we use
+`formatNumber`, which leverages [`toLocaleString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString).
-`formatNumber` formats numbers as strings using the current user locale by default.
+By default, `formatNumber` formats numbers as strings using the current user locale.
-- In JavaScript
+- In JavaScript:
```javascript
import { formatNumber } from '~/locale';
@@ -509,7 +512,7 @@ const tenThousand = formatNumber(10000); // "10,000" (uses comma as decimal symb
const fiftyPercent = formatNumber(0.5, { style: 'percent' }) // "50%" (other options are passed to toLocaleString)
```
-- In Vue templates
+- In Vue templates:
```html
<script>
@@ -546,27 +549,29 @@ console.log(dateFormat.format(new Date('2063-04-05'))) // April 5, 2063
This makes use of [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat).
-- In Ruby/HAML, we have two ways of adding format to dates and times:
+- In Ruby/HAML, there are two ways of adding format to dates and times:
- 1. **Through the `l` helper**, i.e. `l(active_session.created_at, format: :short)`. We have some predefined formats for
- [dates](https://gitlab.com/gitlab-org/gitlab/blob/4ab54c2233e91f60a80e5b6fa2181e6899fdcc3e/config/locales/en.yml#L54) and [times](https://gitlab.com/gitlab-org/gitlab/blob/4ab54c2233e91f60a80e5b6fa2181e6899fdcc3e/config/locales/en.yml#L262).
- If you need to add a new format, because other parts of the code could benefit from it,
- you can add it to [en.yml](https://gitlab.com/gitlab-org/gitlab/blob/master/config/locales/en.yml) file.
- 1. **Through `strftime`**, i.e. `milestone.start_date.strftime('%b %-d')`. We use `strftime` in case none of the formats
- defined on [en.yml](https://gitlab.com/gitlab-org/gitlab/blob/master/config/locales/en.yml) matches the date/time
- specifications we need, and if there is no need to add it as a new format because is very particular (i.e. it's only used in a single view).
+ - **Using the `l` helper**: for example, `l(active_session.created_at, format: :short)`. We have
+ some predefined formats for [dates](https://gitlab.com/gitlab-org/gitlab/-/blob/4ab54c2233e91f60a80e5b6fa2181e6899fdcc3e/config/locales/en.yml#L54)
+ and [times](https://gitlab.com/gitlab-org/gitlab/-/blob/4ab54c2233e91f60a80e5b6fa2181e6899fdcc3e/config/locales/en.yml#L262).
+ If you need to add a new format, because other parts of the code could benefit from it, add it
+ to the file [`en.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/locales/en.yml).
+ - **Using `strftime`**: for example, `milestone.start_date.strftime('%b %-d')`. We use `strftime`
+ in case none of the formats defined in [`en.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/locales/en.yml)
+ match the date/time specifications we need, and if there's no need to add it as a new format
+ because it's very particular (for example, it's only used in a single view).
## Best practices
### Minimize translation updates
-Updates can result in the loss of the translations for this string. To minimize risks,
-avoid changes to strings, unless they:
+Updates can result in the loss of the translations for this string. To minimize risks, avoid changes
+to strings unless they:
-- Add value to the user.
+- Add value for the user.
- Include extra context for translators.
-For example, we should avoid changes like this:
+For example, avoid changes like this:
```diff
- _('Number of things: %{count}') % { count: 10 }
@@ -582,9 +587,10 @@ Examples:
- Mappings for a dropdown list
- Error messages
-To store these kinds of data, using a constant seems like the best choice, however this doesn't work for translations.
+To store these kinds of data, using a constant seems like the best choice. However, this doesn't
+work for translations.
-Bad, avoid it:
+For example, avoid this:
```ruby
class MyPresenter
@@ -596,11 +602,13 @@ class MyPresenter
end
```
-The translation method (`_`) is called when the class is loaded for the first time and translates the text to the default locale. Regardless of the user's locale, these values are not translated a second time.
+The translation method (`_`) is called when the class loads for the first time and translates the
+text to the default locale. Regardless of the user's locale, these values are not translated a
+second time.
-Similar thing happens when using class methods with memoization.
+A similar thing happens when using class methods with memoization.
-Bad, avoid it:
+For example, avoid this:
```ruby
class MyModel
@@ -614,7 +622,7 @@ class MyModel
end
```
-This method memorizes the translations using the locale of the user, who first "called" this method.
+This method memoizes the translations using the locale of the user who first called this method.
To avoid these problems, keep the translations dynamic.
@@ -634,10 +642,10 @@ end
### Splitting sentences
-Please never split a sentence as that would assume the sentence grammar and
-structure is the same in all languages.
+Never split a sentence, as it assumes the sentence's grammar and structure is the same in all
+languages.
-For instance, the following:
+For example, this:
```javascript
{{ s__("mrWidget|Set by") }}
@@ -645,7 +653,7 @@ For instance, the following:
{{ s__("mrWidget|to be merged automatically when the pipeline succeeds") }}
```
-should be externalized as follows:
+Should be externalized as follows:
```javascript
{{ sprintf(s__("mrWidget|Set by %{author} to be merged automatically when the pipeline succeeds"), { author: author.name }) }}
@@ -653,7 +661,8 @@ should be externalized as follows:
#### Avoid splitting sentences when adding links
-This also applies when using links in between translated sentences, otherwise these texts are not translatable in certain languages.
+This also applies when using links in between translated sentences. Otherwise, these texts are not
+translatable in certain languages.
- In Ruby/HAML, instead of:
@@ -662,7 +671,7 @@ This also applies when using links in between translated sentences, otherwise th
= s_('ClusterIntegration|Learn more about %{zones_link}').html_safe % { zones_link: zones_link }
```
- Set the link starting and ending HTML fragments as variables like so:
+ Set the link starting and ending HTML fragments as variables:
```haml
- zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
@@ -687,7 +696,7 @@ This also applies when using links in between translated sentences, otherwise th
</template>
```
- Set the link starting and ending HTML fragments as placeholders like so:
+ Set the link starting and ending HTML fragments as placeholders:
```html
<template>
@@ -714,7 +723,7 @@ This also applies when using links in between translated sentences, otherwise th
}}
```
- Set the link starting and ending HTML fragments as placeholders like so:
+ Set the link starting and ending HTML fragments as placeholders:
```javascript
{{
@@ -725,50 +734,47 @@ This also applies when using links in between translated sentences, otherwise th
}}
```
-The reasoning behind this is that in some languages words change depending on context. For example in Japanese は is added to the subject of a sentence and を to the object. This is impossible to translate correctly if we extract individual words from the sentence.
+The reasoning behind this is that in some languages words change depending on context. For example,
+in Japanese は is added to the subject of a sentence and を to the object. This is impossible to
+translate correctly if you extract individual words from the sentence.
-When in doubt, try to follow the best practices described in this [Mozilla
-Developer documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices#Splitting).
+When in doubt, try to follow the best practices described in this [Mozilla Developer documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices#Splitting).
## Updating the PO files with the new content
-Now that the new content is marked for translation, we need to update
-`locale/gitlab.pot` files with the following command:
+Now that the new content is marked for translation, run this command to update the
+`locale/gitlab.pot` files:
```shell
bin/rake gettext:regenerate
```
-This command updates `locale/gitlab.pot` file with the newly externalized
-strings and remove any strings that aren't used anymore. You should check this
-file in. Once the changes are on the default branch, they are picked up by
-[CrowdIn](https://translate.gitlab.com) and be presented for
-translation.
+This command updates the `locale/gitlab.pot` file with the newly externalized strings and removes
+any unused strings. Once the changes are on the default branch, [CrowdIn](https://translate.gitlab.com)
+picks them up and presents them for translation.
-We don't need to check in any changes to the `locale/[language]/gitlab.po` files.
-They are updated automatically when [translations from CrowdIn are merged](merging_translations.md).
+You don't need to check in any changes to the `locale/[language]/gitlab.po` files. They are updated
+automatically when [translations from CrowdIn are merged](merging_translations.md).
-If there are merge conflicts in the `gitlab.pot` file, you can delete the file
-and regenerate it using the same command.
+If there are merge conflicts in the `gitlab.pot` file, you can delete the file and regenerate it
+using the same command.
### Validating PO files
-To make sure we keep our translation files up to date, there's a linter that is
-running on CI as part of the `static-analysis` job.
-
-To lint the adjustments in PO files locally you can run `rake gettext:lint`.
+To make sure we keep our translation files up to date, there's a linter that runs on CI as part of
+the `static-analysis` job. To lint the adjustments in PO files locally, you can run
+`rake gettext:lint`.
The linter takes the following into account:
-- Valid PO-file syntax
-- Variable usage
- - Only one unnamed (`%d`) variable, since the order of variables might change
- in different languages
- - All variables used in the message ID are used in the translation
- - There should be no variables used in a translation that aren't in the
- message ID
+- Valid PO-file syntax.
+- Variable usage.
+ - Only one unnamed (`%d`) variable, since the order of variables might change in different
+ languages.
+ - All variables used in the message ID are used in the translation.
+ - There should be no variables used in a translation that aren't in the message ID.
- Errors during translation.
-- Presence of angle brackets (`<` or `>`)
+- Presence of angle brackets (`<` or `>`).
The errors are grouped per file, and per message ID:
@@ -789,9 +795,8 @@ Errors in `locale/zh_TW/gitlab.po`:
Failure translating to zh_TW with []: too few arguments
```
-In this output the `locale/zh_HK/gitlab.po` has syntax errors.
-The `locale/zh_TW/gitlab.po` has variables that are used in the translation that
-aren't in the message with ID `1 pipeline`.
+In this output, `locale/zh_HK/gitlab.po` has syntax errors. The file `locale/zh_TW/gitlab.po` has
+variables in the translation that aren't in the message with ID `1 pipeline`.
## Adding a new language
@@ -803,9 +808,9 @@ NOTE:
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221012) in GitLab 13.3:
Languages with less than 2% of translations are not available in the UI.
-Let's suppose you want to add translations for a new language, let's say French.
+Suppose you want to add translations for a new language, for example, French:
-1. The first step is to register the new language in `lib/gitlab/i18n.rb`:
+1. Register the new language in `lib/gitlab/i18n.rb`:
```ruby
...
@@ -816,38 +821,33 @@ Let's suppose you want to add translations for a new language, let's say French.
...
```
-1. Next, you need to add the language:
+1. Add the language:
```shell
bin/rake gettext:add_language[fr]
```
- If you want to add a new language for a specific region, the command is similar,
- you just need to separate the region with an underscore (`_`). For example:
+ If you want to add a new language for a specific region, the command is similar. You must
+ separate the region with an underscore (`_`), specify the region in capital letters. For example:
```shell
bin/rake gettext:add_language[en_GB]
```
- Please note that you need to specify the region part in capitals.
-
-1. Now that the language is added, a new directory has been created under the
- path: `locale/fr/`. You can now start using your PO editor to edit the PO file
- located in: `locale/fr/gitlab.edit.po`.
+1. Adding the language also creates a new directory at the path `locale/fr/`. You can now start
+ using your PO editor to edit the PO file located at `locale/fr/gitlab.edit.po`.
-1. After you're done updating the translations, you need to process the PO files
- in order to generate the binary MO files and finally update the JSON files
- containing the translations:
+1. After updating the translations, you must process the PO files to generate the binary MO files,
+ and update the JSON files containing the translations:
```shell
bin/rake gettext:compile
```
-1. In order to see the translated content we need to change our preferred language
- which can be found under the user's **Settings** (`/profile`).
+1. To see the translated content, you must change your preferred language. You can find this under
+ the user's **Settings** (`/profile`).
-1. After checking that the changes are ok, you can proceed to commit the new files.
- For example:
+1. After checking that the changes are ok, commit the new files. For example:
```shell
git add locale/fr/ app/assets/javascripts/locale/fr/
diff --git a/doc/development/i18n/index.md b/doc/development/i18n/index.md
index b0e34052d2a..c22bb6ff020 100644
--- a/doc/development/i18n/index.md
+++ b/doc/development/i18n/index.md
@@ -6,52 +6,49 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Translate GitLab to your language
-The text in the GitLab user interface is in American English by default.
-Each string can be translated to other languages.
-As each string is translated, it is added to the languages translation file,
-and is made available in future releases of GitLab.
+The text in the GitLab user interface is in American English by default. Each string can be
+translated to other languages. As each string is translated, it's added to the languages translation
+file and made available in future GitLab releases.
-Contributions to translations are always needed.
-Many strings are not yet available for translation because they have not been externalized.
-Helping externalize strings benefits all languages.
-Some translations are incomplete or inconsistent.
-Translating strings helps complete and improve each language.
-
-## How to contribute
+Contributions to translations are always needed. Many strings are not yet available for translation
+because they have not been externalized. Helping externalize strings benefits all languages. Some
+translations are incomplete or inconsistent. Translating strings helps complete and improve each
+language.
There are many ways you can contribute in translating GitLab.
-### Externalize strings
+## Externalize strings
-Before a string can be translated, it must be externalized.
-This is the process where English strings in the GitLab source code are wrapped in a function that
-retrieves the translated string for the user's language.
+Before a string can be translated, it must be externalized. This is the process where English
+strings in the GitLab source code are wrapped in a function that retrieves the translated string for
+the user's language.
-As new features are added and existing features are updated, the surrounding strings are being
-externalized, however, there are many parts of GitLab that still need more work to externalize all
+As new features are added and existing features are updated, the surrounding strings are
+externalized. However, there are many parts of GitLab that still need more work to externalize all
strings.
See [Externalization for GitLab](externalization.md).
-### Translate strings
+## Translate strings
-The translation process is managed at <https://translate.gitlab.com>
+The translation process is managed at [https://translate.gitlab.com](https://translate.gitlab.com)
using [CrowdIn](https://crowdin.com/).
-You need to create an account before you can submit translations.
-Once you are signed in, select the language you wish to contribute translations to.
+You must create a CrowdIn account before you can submit translations. Once you are signed in, select
+the language you wish to contribute translations to.
-Voting for translations is also valuable, helping to confirm good and flag inaccurate translations.
+Voting for translations is also valuable, helping to confirm good translations and flag inaccurate
+ones.
See [Translation guidelines](translation.md).
-### Proofreading
+## Proofreading
-Proofreading helps ensure the accuracy and consistency of translations. All
-translations are proofread before being accepted. If a translations requires
-changes, you are notified with a comment explaining why.
+Proofreading helps ensure the accuracy and consistency of translations. All translations are
+proofread before being accepted. If a translation requires changes, a comment explaining why
+notifies you.
-See [Proofreading Translations](proofreader.md) for more information on who's
-able to proofread and instructions on becoming a proofreader yourself.
+See [Proofreading Translations](proofreader.md) for more information on who can proofread and
+instructions on becoming a proofreader yourself.
## Release
diff --git a/doc/development/i18n/merging_translations.md b/doc/development/i18n/merging_translations.md
index 48474a68d16..e3211f5a8fc 100644
--- a/doc/development/i18n/merging_translations.md
+++ b/doc/development/i18n/merging_translations.md
@@ -9,43 +9,42 @@ info: To determine the technical writer assigned to the Stage/Group associated w
CrowdIn automatically syncs the `gitlab.pot` file with the CrowdIn service, presenting
newly added externalized strings to the community of translators.
-[GitLab CrowdIn Bot](https://gitlab.com/gitlab-crowdin-bot) also creates merge requests
+The [GitLab CrowdIn Bot](https://gitlab.com/gitlab-crowdin-bot) also creates merge requests
to take newly approved translation submissions and merge them into the `locale/<language>/gitlab.po`
-files. Check the [merge requests created by `gitlab-crowdin-bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests?scope=all&utf8=%E2%9C%93&state=opened&author_username=gitlab-crowdin-bot)
+files. Check the [merge requests created by `gitlab-crowdin-bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests?scope=all&state=opened&author_username=gitlab-crowdin-bot)
to see new and merged merge requests.
## Validation
By default CrowdIn commits translations with `[skip ci]` in the commit
-message. This is done to avoid a bunch of pipelines being run. Before
-merging translations, make sure to trigger a pipeline to validate
-translations, we have static analysis validating things CrowdIn
-doesn't do. Create a new pipeline at `https://gitlab.com/gitlab-org/gitlab/pipelines/new`
-(need Developer access permissions) for the `master-i18n` branch.
+message. This avoids an excessive number of pipelines from running.
+Before merging translations, make sure to trigger a pipeline to validate
+translations. Static analysis validates things CrowdIn doesn't do. Create
+a new pipeline at [`https://gitlab.com/gitlab-org/gitlab/pipelines/new`](https://gitlab.com/gitlab-org/gitlab/pipelines/new)
+(need developer permissions) for the `master-i18n` branch.
If there are validation errors, the easiest solution is to disapprove
the offending string in CrowdIn, leaving a comment with what is
-required to fix the offense. There is an
+required to fix the errors. There's an
[issue](https://gitlab.com/gitlab-org/gitlab/-/issues/23256)
-suggesting to automate this process. Disapproving excludes the
-invalid translation, the merge request is then updated within a few
+that suggests automating this process. Disapproving excludes the
+invalid translation. The merge request is then updated within a few
minutes.
-If the translation has failed validation due to angle brackets `<` or `>`
-it should be disapproved on CrowdIn as our strings should be
-using [variables](externalization.md#html) for HTML instead.
+If the translation fails validation due to angle brackets (`<` or `>`),
+it should be disapproved in CrowdIn. Our strings must use [variables](externalization.md#html)
+for HTML instead.
-It might be handy to pause the integration on the CrowdIn side for a
-little while so translations don't keep coming. This can be done by
-clicking `Pause sync` on the [CrowdIn integration settings
-page](https://translate.gitlab.com/project/gitlab-ee/settings#integration).
+It might be useful to pause the integration on the CrowdIn side for a
+moment so translations don't keep coming. You can do this by clicking
+**Pause sync** on the [CrowdIn integration settings page](https://translate.gitlab.com/project/gitlab-ee/settings#integration).
## Merging translations
After all translations are determined to be appropriate and the pipelines pass,
you can merge the translations into the default branch. When merging translations,
-be sure to select the **Remove source branch** check box, which causes CrowdIn
-to recreate the `master-i18n` from the default branch after merging the new
+be sure to select the **Remove source branch** checkbox. This causes CrowdIn
+to recreate the `master-i18n` branch from the default branch after merging the new
translation.
We are discussing [automating this entire process](https://gitlab.com/gitlab-org/gitlab/-/issues/19896).
@@ -54,10 +53,8 @@ We are discussing [automating this entire process](https://gitlab.com/gitlab-org
CrowdIn creates a new merge request as soon as the old one is closed
or merged. But it does not recreate the `master-i18n` branch every
-time. To force CrowdIn to recreate the branch, close any [open merge
-request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests?scope=all&utf8=%E2%9C%93&state=opened&author_username=gitlab-crowdin-bot)
-and delete the
-[`master-18n`](https://gitlab.com/gitlab-org/gitlab/-/branches/all?utf8=✓&search=master-i18n).
+time. To force CrowdIn to recreate the branch, close any [open merge requests](https://gitlab.com/gitlab-org/gitlab/-/merge_requests?scope=all&state=opened&author_username=gitlab-crowdin-bot)
+and delete the [`master-18n`](https://gitlab.com/gitlab-org/gitlab/-/branches/all?utf8=✓&search=master-i18n) branch.
This might be needed when the merge request contains failures that
have been fixed on the default branch.
@@ -76,8 +73,8 @@ recreate it with the following steps:
1. Sign in to CrowdIn with the GitLab integration.
1. Go to **Settings > Integrations > GitLab > Set Up Integration**.
1. Select the `gitlab-org/gitlab` repository.
-1. In `Select Branches for Translation`, select `master`.
-1. Ensure the `Service Branch Name` is `master-i18n`.
+1. In **Select Branches for Translation**, select `master`.
+1. Ensure the **Service Branch Name** is `master-i18n`.
## Manually update the translation levels
@@ -85,3 +82,9 @@ There's no automated way to pull the translation levels from CrowdIn, to display
this information in the language selection dropdown. Therefore, the translation
levels are hard-coded in the `TRANSLATION_LEVELS` constant in [`i18n.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/i18n.rb),
and must be regularly updated.
+
+To update the translation levels:
+
+1. Get the translation levels (percentage of approved words) from [Crowdin](https://crowdin.com/project/gitlab-ee/settings#translations).
+
+1. Update the hard-coded translation levels in [`i18n.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/i18n.rb#L40).
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index a15eb4c3bc2..fc19ab93ecd 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -87,6 +87,7 @@ are very appreciative of the work done by translators and proofreaders!
- Polish
- Filip Mech - [GitLab](https://gitlab.com/mehenz), [CrowdIn](https://crowdin.com/profile/mehenz)
- Maksymilian Roman - [GitLab](https://gitlab.com/villaincandle), [CrowdIn](https://crowdin.com/profile/villaincandle)
+ - Jakub Gładykowski - [GitLab](https://gitlab.com/gladykov), [CrowdIn](https://crowdin.com/profile/gladykov)
- Portuguese
- Diogo Trindade - [GitLab](https://gitlab.com/luisdiogo2071317), [CrowdIn](https://crowdin.com/profile/ldiogotrindade)
- Portuguese, Brazilian
@@ -108,7 +109,7 @@ are very appreciative of the work done by translators and proofreaders!
- Spanish
- Pedro Garcia - [GitLab](https://gitlab.com/pedgarrod), [CrowdIn](https://crowdin.com/profile/breaking_pitt)
- Swedish
- - Proofreaders needed.
+ - Johannes Nilsson - [GitLab](https://gitlab.com/nlssn), [CrowdIn](https://crowdin.com/profile/nlssn)
- Turkish
- Ali Demirtaş - [GitLab](https://gitlab.com/alidemirtas), [CrowdIn](https://crowdin.com/profile/alidemirtas)
- Rıfat Ünalmış (Rifat Unalmis) - [GitLab](https://gitlab.com/runalmis), [CrowdIn](https://crowdin.com/profile/runalmis)
@@ -121,35 +122,35 @@ are very appreciative of the work done by translators and proofreaders!
## Become a proofreader
-Before requesting Proofreader permissions in CrowdIn, be sure you have a history
-of contributing translations to the GitLab project.
+Before requesting proofreader permissions in CrowdIn, be sure you have a history of contributing
+translations to the GitLab project.
1. Contribute translations to GitLab. See instructions for
[translating GitLab](translation.md).
- Translating GitLab is a community effort that requires team work and
- attention to detail. Proofreaders play an important role helping new
- contributors, and ensuring the consistency and quality of translations.
- Your conduct and contributions as a translator should reflect this before
- requesting to be a proofreader.
+ Translating GitLab is a community effort that requires teamwork and attention to detail.
+ Proofreaders play an important role helping new contributors, and ensuring the consistency and
+ quality of translations. Your conduct and contributions as a translator should reflect this
+ before requesting to be a proofreader.
+
+1. Request proofreader permissions by opening a merge request to add yourself to the list of
+ proofreaders.
+
+ Open the [`proofreader.md` source file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/development/i18n/proofreader.md) and click **Edit**.
-1. Request proofreader permissions by opening a merge request to add yourself
- to the list of proofreaders.
+ Add your language in alphabetical order and add yourself to the list, including:
- Open the [proofreader.md source file](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/development/i18n/proofreader.md) and click **Edit**.
+ - Name
+ - Link to your GitLab profile
+ - Link to your CrowdIn profile
- Add your language in alphabetical order, and add yourself to the list
- including:
- - name
- - link to your GitLab profile
- - link to your CrowdIn profile
+ In the merge request description, include links to any projects you have previously translated.
- In the merge request description, include links to any projects you have
- previously translated.
+1. [GitLab team members](https://about.gitlab.com/company/team/),
+ [Core team members](https://about.gitlab.com/community/core-team/),
+ or current proofreaders fluent in the language consider your request to become a proofreader
+ based on the merits of your previous translations.
-1. Your request to become a proofreader is considered on the merits of
- your previous translations by [GitLab team members](https://about.gitlab.com/company/team/)
- or [Core team members](https://about.gitlab.com/community/core-team/) who are fluent in
- the language or current proofreaders.
- - When a request is made for the first proofreader for a language and there are no [GitLab team members](https://about.gitlab.com/company/team/)
- or [Core team members](https://about.gitlab.com/community/core-team/) who speak the language, we shall request links to previous translation work in other communities or projects.
+ - If you request to become the first proofreader for a language and there are no GitLab or Core
+ team members who speak that language, we request links to previous translation work in other
+ communities or projects.
diff --git a/doc/development/i18n/translation.md b/doc/development/i18n/translation.md
index f3d02e180e7..f2592d9a8b9 100644
--- a/doc/development/i18n/translation.md
+++ b/doc/development/i18n/translation.md
@@ -6,47 +6,39 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Translating GitLab
-For managing the translation process we use [CrowdIn](https://crowdin.com).
+For managing the translation process, we use [CrowdIn](https://crowdin.com).
+To contribute translations at [`translate.gitlab.com`](https://translate.gitlab.com),
+you must create a CrowdIn account. You may create a new account or use any of their supported
+sign-in services.
-## Using CrowdIn
+## Language selections
-The first step is to get familiar with CrowdIn.
+GitLab is being translated into many languages. To select a language to contribute to:
-### Sign In
+1. Find the language that you want to contribute to, in the
+ [GitLab CrowdIn project](https://crowdin.com/project/gitlab-ee).
-To contribute translations at <https://translate.gitlab.com>
-you must create a CrowdIn account.
-You may create a new account or use any of their supported sign in services.
+ - If the language you want is available, proceed to the next step.
+ - If the language you want is not available,
+ [open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
+ Notify our CrowdIn administrators by including `@gitlab-org/manage/import` in your issue.
+ - After the issue and any merge requests are complete, restart this procedure.
-### Language Selections
+1. View the list of files and folders. Select `gitlab.pot` to open the translation editor.
-GitLab is being translated into many languages.
-
-1. Find the language that you want to contribute to, in our
- [GitLab Crowdin project](https://crowdin.com/project/gitlab-ee).
- - If the language that you're looking for is available, proceed
- to the next step.
- - If the language you are looking for is not available,
- [open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization). Notify our Crowdin
- administrators by including `@gitlab-org/manage/import` in your issue.
- - After the issue/Merge Request is complete, restart this procedure.
-1. Next, you can view list of files and folders.
- Select `gitlab.pot` to open the translation editor.
-
-### Translation Editor
+### Translation editor
The online translation editor is the easiest way to contribute translations.
![CrowdIn Editor](img/crowdin-editor.png)
-1. Strings for translation are listed in the left panel
-1. Translations are entered into the central panel.
- Multiple translations are required for strings that contains plurals.
- The string to be translated is shown above with glossary terms highlighted.
- If the string to be translated is not clear, you can 'Request Context'
+- Strings for translation are listed in the left panel.
+- Translations are entered into the central panel. Multiple translations are required for strings
+ that contain plurals. The string to translate is shown in the above image with glossary terms
+ highlighted. If the string to translate isn't clear, you can request context.
-A glossary of common terms is available in the right panel by clicking Terms.
-Comments can be added to discuss a translation with the community.
+A glossary of common terms is available in the **Terms** tab in the right panel. In the **Comments**
+tab, you can add comments to discuss a translation with the community.
Remember to **Save** each translation.
@@ -56,21 +48,18 @@ Be sure to check the following guidelines before you translate any strings.
### Namespaced strings
-When an externalized string is prepended with a namespace, e.g.
-`s_('OpenedNDaysAgo|Opened')`, the namespace should be removed from the final
-translation.
-For example in French `OpenedNDaysAgo|Opened` would be translated to
-`Ouvert•e`, not `OpenedNDaysAgo|Ouvert•e`.
+When an externalized string is prepended with a namespace (for example,
+`s_('OpenedNDaysAgo|Opened')`), the namespace should be removed from the final translation. For
+example, in French, `OpenedNDaysAgo|Opened` is translated to `Ouvert•e`, not
+`OpenedNDaysAgo|Ouvert•e`.
### Technical terms
-Some technical terms should be treated like proper nouns and not be translated.
-
-Technical terms that should always be in English are noted in the glossary when
-using <https://translate.gitlab.com>.
-
-This helps maintain a logical connection and consistency between tools (e.g.
-`git` client) and GitLab.
+You should treat some technical terms like proper nouns and not translate them. Technical terms that
+should always be in English are noted in the glossary when using
+[`translate.gitlab.com`](https://translate.gitlab.com).
+This helps maintain a logical connection and consistency between tools (for example, a Git client)
+and GitLab.
### Formality
@@ -78,36 +67,33 @@ The level of formality used in software varies by language:
| Language | Formality | Example |
| -------- | --------- | ------- |
-| French | formal | `vous` for `you` |
-| German | informal | `du` for `you` |
+| French | formal | `vous` for `you` |
+| German | informal | `du` for `you` |
-You can refer to other translated strings and notes in the glossary to assist
-determining a suitable level of formality.
+Refer to other translated strings and notes in the glossary to assist you in determining a suitable
+level of formality.
### Inclusive language
-[Diversity](https://about.gitlab.com/handbook/values/#diversity) is a GitLab value.
-We ask you to avoid translations which exclude people based on their gender or
-ethnicity.
-In languages which distinguish between a male and female form, use both or
-choose a neutral formulation.
+[Diversity, inclusion, and belonging](https://about.gitlab.com/handbook/values/#diversity-inclusion)
+are GitLab values. We ask you to avoid translations that exclude people based on their gender or
+ethnicity. In languages that distinguish between a male and female form, use both or choose a
+neutral formulation.
<!-- vale gitlab.Spelling = NO -->
-For example in German, the word "user" can be translated into "Benutzer" (male) or "Benutzerin" (female).
-Therefore "create a new user" would translate into "Benutzer(in) anlegen".
+For example, in German, the word _user_ can be translated into _Benutzer_ (male) or _Benutzerin_
+(female). Therefore, _create a new user_ translates to _Benutzer(in) anlegen_.
<!-- vale gitlab.Spelling = YES -->
### Updating the glossary
-To propose additions to the glossary please
+To propose additions to the glossary, please
[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
-## French Translation Guidelines
-
-### Inclusive language in French
+## French translation guidelines
<!-- vale gitlab.Spelling = NO -->
-In French, the "écriture inclusive" is now over (see on [Legifrance](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000036068906/)).
-So, to include both genders, write "Utilisateurs et utilisatrices" instead of "Utilisateur·rice·s".
-When space is missing, the male gender should be used alone.
+In French, the _écriture inclusive_ is now over (see on [Legifrance](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000036068906/)).
+To include both genders, write _Utilisateurs et utilisatrices_ instead of _Utilisateur·rice·s_. If
+there is not enough space, use the male gender alone.
<!-- vale gitlab.Spelling = YES -->