Compare commits

...
Sign in to create a new pull request.

8 commits

Author SHA1 Message Date
Michael Telatynski
1e8f48bf21
Update docs 2023-08-24 11:07:36 +01:00
Michael Telatynski
cd025a4f8a
Update docs 2023-08-24 10:56:08 +01:00
Michael Telatynski
84318eeb81
Update matrix-web-i18n 2023-08-24 10:55:00 +01:00
Michael Telatynski
f0e74abb2b
Iterate 2023-08-23 11:06:24 +01:00
Michael Telatynski
4a46245fc9
Prettier 2023-08-23 09:22:53 +01:00
Michael Telatynski
e708ab16fe
Update README 2023-08-22 19:00:23 +01:00
Michael Telatynski
fa1fcf4f94
Remove prunei18n 2023-08-22 16:17:58 +01:00
Michael Telatynski
4489fd1aca
Update docs regarding Localazy 2023-08-22 16:17:26 +01:00
5 changed files with 53 additions and 66 deletions

View file

@ -1,7 +1,7 @@
[![Chat](https://img.shields.io/matrix/element-web:matrix.org?logo=matrix)](https://matrix.to/#/#element-web:matrix.org)
![Tests](https://github.com/vector-im/element-web/actions/workflows/tests.yaml/badge.svg)
![Static Analysis](https://github.com/vector-im/element-web/actions/workflows/static_analysis.yaml/badge.svg)
[![Weblate](https://translate.element.io/widgets/element-web/-/element-web/svg-badge.svg)](https://translate.element.io/engage/element-web/)
[![Localazy](https://img.shields.io/endpoint?url=https%3A%2F%2Fconnect.localazy.com%2Fstatus%2Felement-web%2Fdata%3Fcontent%3Dall%26title%3Dlocalazy%26logo%3Dtrue)](https://localazy.com/p/element-web)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=element-web)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=coverage)](https://sonarcloud.io/summary/new_code?id=element-web)
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=element-web)
@ -388,8 +388,6 @@ To add a new translation, head to the [translating doc](docs/translating.md).
For a developer guide, see the [translating dev doc](docs/translating-dev.md).
[<img src="https://translate.element.io/widgets/element-web/-/multi-auto.svg" alt="translationsstatus" width="340">](https://translate.element.io/engage/element-web/?utm_source=widget)
# Triaging issues
Issues are triaged by community members and the Web App Team, following the [triage process](https://github.com/vector-im/element-meta/wiki/Triage-process).

View file

@ -6,11 +6,16 @@
- Including up-to-date versions of matrix-react-sdk and matrix-js-sdk
- Latest LTS version of Node.js installed
- Be able to understand English
- Be able to understand the language you want to translate Element into
## Translating strings vs. marking strings for translation
Translating strings are done with the `_t()` function found in matrix-react-sdk/lib/languageHandler.js. It is recommended to call this function wherever you introduce a string constant which should be translated. However, translating can not be performed until after the translation system has been initialized. Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced. This breaks some tooling and makes it difficult to find translatable strings. Therefore, there is the alternative `_td()` function which is used to mark strings for translation, without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).
Translating strings are done with the `_t()` function found in matrix-react-sdk/lib/languageHandler.js.
It is recommended to call this function wherever you introduce a string constant which should be translated.
However, translating can not be performed until after the translation system has been initialized.
Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced.
This breaks some tooling and makes it difficult to find translatable strings.
Therefore, there is the alternative `_td()` function which is used to mark strings for translation,
without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).
Basically, whenever a translatable string is introduced, you should call either `_t()` immediately OR `_td()` and later `_t()`.
@ -29,24 +34,36 @@ function getColorName(hex) {
}
```
## Key naming rules
These rules are based on https://github.com/vector-im/element-x-android/blob/develop/tools/localazy/README.md
At this time we are not trying to have a translation key per UI element as some methodologies use,
whilst that would offer the greatest flexibility, it would also make reuse between projects nigh impossible.
We are aiming for a set of common strings to be shared then some more localised translations per context they may appear in.
1. Ensure the string doesn't already exist in a related project, such as https://localazy.com/p/element
2. Keys for common strings, i.e. strings that can be used at multiple places must start by `action_` if this is a verb, or `common_` if not
3. Keys for common accessibility strings must start by `a11y_`. Example:` a11y_hide_password`
4. Otherwise, try to group keys logically and nest where appropriate, such as `keyboard_` for strings relating to keyboard shortcuts.
5. Ensure your translation keys do not include `.` or `|` or ` `. Try to balance string length against descriptiveness.
## Adding new strings
1. Check if the import `import { _t } from 'matrix-react-sdk/src/languageHandler';` is present. If not add it to the other import statements. Also import `_td` if needed.
1. Add `_t()` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method). If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
1. Run `yarn i18n` to update `src/i18n/strings/en_EN.json`
1. If you added a string with a plural, you can add other English plural variants to `src/i18n/strings/en_EN.json` (remeber to edit the one in the same project as the source file containing your new translation).
1. Add `_t()` to your string passing the translation key you come up with based on the rules above. If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
1. Run `yarn i18n` to add the keys to `src/i18n/strings/en_EN.json`
1. Modify the new entries in `src/i18n/strings/en_EN.json` with the English (UK) translations for the added keys.
## Editing existing strings
1. Edit every occurrence of the string inside `_t()` and `_td()` in the JSX files.
1. Run `yarn i18n` to update `src/i18n/strings/en_EN.json`. (Be sure to run this in the same project as the JSX files you just edited.)
1. Run `yarn prunei18n` to remove the old string from `src/i18n/strings/*.json`.
Edits to existing strings should be performed only via Localazy.
There you can also require all translations to be redone if the meaning of the string has changed significantly.
## Adding variables inside a string.
1. Extend your `_t()` call. Instead of `_t(STRING)` use `_t(STRING, {})`
1. Extend your `_t()` call. Instead of `_t(TKEY)` use `_t(TKEY, {})`
1. Decide how to name it. Please think about if the person who has to translate it can understand what it does. E.g. using the name 'recipient' is bad, because a translator does not know if it is the name of a person, an email address, a user ID, etc. Rather use e.g. recipientEmailAddress.
1. Add it to the array in `_t` for example `_t(STRING, {variable: this.variable})`
1. Add it to the array in `_t` for example `_t(TKEY, {variable: this.variable})`
1. Add the variable inside the string. The syntax for variables is `%(variable)s`. Please note the _s_ at the end. The name of the variable has to match the previous used name.
- You can use the special `count` variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. `_t('You have %(count)s new messages', { count: 2 })` would show 'You have 2 new messages', while `_t('You have %(count)s new messages', { count: 1 })` would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in `count` is much prefered over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
@ -61,4 +78,5 @@ function getColorName(hex) {
- Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
- Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
- Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetion, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetition, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.
- Don't forget curly braces when you assign an expression to JSX attributes in the render method)

View file

@ -1,63 +1,33 @@
# How to translate Element
# 🚨 Translations are currently frozen as we are migrating Translation Management Systems! 🚨
## Requirements
- Web Browser
- Be able to understand English
- Be able to understand the language you want to translate Element into
## Step 0: Join #element-translations:matrix.org
## Join #element-translations:matrix.org
1. Come and join https://matrix.to/#/#element-translations:matrix.org for general discussion
2. Join https://matrix.to/#/#element-translators:matrix.org for language-specific rooms
3. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :)
## Step 1: Preparing your Weblate Profile
1. Head to https://translate.element.io and register either via Github or email
2. After registering check if you got an email to verify your account and click the link (if there is none head to step 1.4)
3. Log into weblate
4. Head to https://translate.element.io/accounts/profile/ and select the languages you know and maybe another language you know too.
## How to check if your language already is being translated
Go to https://translate.element.io/projects/element-web/ and visit the 2 sub-projects.
If your language is listed go to Step 2a and if not go to Step 2b
Go to https://localazy.com/p/element-web
If your language is listed then you can get started, have a read of https://localazy.com/docs/general/translating-strings
if you need help getting started. If your language is not yet listed please express your wishes to start translating it in
the general discussion room linked above.
## Step 2a: Helping on existing languages.
### What are `%(something)s`?
1. Head to one of the projects listed https://translate.element.io/projects/element-web/
2. Click on the `translate` button on the right side of your language
3. Fill in the translations in the writeable field. You will see the original English string and the string of your second language above.
These things are placeholders that are expanded when displayed by Element. They can be room names, usernames or similar.
If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
A special case is `%(count)s` as this is also used to determine which pluralisation is used.
Head to the explanations under Steb 2b
### What are `<link>Something</link>`
## Step 2b: Adding a new language
1. Go to one of the projects listed https://translate.element.io/projects/element-web/
2. Click the `Start new translation` button at the bottom
3. Select a language
4. Start translating like in 2a.3
5. Repeat these steps for the other projects which are listed at the link of step 2b.1
### What means the green button under the text field?
The green button let you save our translations directly. Please only use it if you are 100% sure about that translation. If you do not know a translation please DO NOT click that button. Use the arrows above the translations field and click to the right.
### What means the yellow button under the text field?
The yellow button has to be used if you are unsure about the translation but you have a rough idea. It adds a new suggestion to the string which can than be reviewed by others.
### What are "%(something)s"?
These things are variables that are expanded when displayed by Element. They can be room names, usernames or similar. If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
A special case is `%(urlStart)s` and `%(urlEnd)s` which are used to mark the beginning of a hyperlink (i.e. `<a href="/somewhere">` and `</a>`. You must keep these markers surrounding the equivalent string in your language that needs to be hyperlinked.
### "I want to come back to this string. How?"
You can use inside the translation field "Review needed" checkbox. It will be shown as Strings that need to be reviewed.
### Further reading
The official Weblate doc provides some more in-depth explanation on how to do translations and talks about do and don'ts. You can find it at: https://docs.weblate.org/en/latest/user/translating.html
These things are markup tags, they encapsulate sections of translations to be marked up, with links, buttons, emphasis and such.
You must keep these markers surrounding the equivalent string in your language that needs to be marked up.

View file

@ -31,7 +31,6 @@
],
"scripts": {
"i18n": "matrix-gen-i18n",
"prunei18n": "matrix-prune-i18n",
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && matrix-gen-i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
"clean": "rimraf lib webapp",
"build": "yarn clean && yarn build:genfiles && yarn build:bundle",
@ -146,7 +145,7 @@
"json-loader": "^0.5.7",
"loader-utils": "^3.0.0",
"matrix-mock-request": "^2.5.0",
"matrix-web-i18n": "^2.0.0",
"matrix-web-i18n": "^3.0.0",
"mini-css-extract-plugin": "^1",
"minimist": "^1.2.6",
"mkdirp": "^3.0.0",

View file

@ -8685,13 +8685,15 @@ matrix-mock-request@^2.5.0:
what-input "^5.2.10"
zxcvbn "^4.4.2"
matrix-web-i18n@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/matrix-web-i18n/-/matrix-web-i18n-2.0.0.tgz#fe43c9e4061410cef4b8663527ee692296ce023b"
integrity sha512-bMn4MsWKnzzfQPVAfgmlMXa1rqVS1kUuTQ//d+Zsze2hGX8pTB1y3qFLYhkgAgVcx89FxiVL7Kw9dUzllvwgOg==
matrix-web-i18n@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matrix-web-i18n/-/matrix-web-i18n-3.0.0.tgz#23fe255ab9c7c19a4276608ce2219ca837e2ad58"
integrity sha512-82UqBV53VJhLZcb4/9oMQpAAWav2Vk+DtUyTzdTl5ZkQ/eLeeICm7xy4p2/aK1jeN7ppN82yBs2gxx7t7eX67A==
dependencies:
"@babel/parser" "^7.18.5"
"@babel/traverse" "^7.18.5"
lodash "^4.17.21"
minimist "^1.2.8"
walk "^2.3.15"
matrix-widget-api@^1.3.1, matrix-widget-api@^1.5.0:
@ -8949,7 +8951,7 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"
minimist@>=1.2.2, minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
minimist@>=1.2.2, minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==