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

Mark and remove some translations #5110

Merged
merged 4 commits into from Oct 4, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 12 additions & 4 deletions docs/translating-dev.md
Expand Up @@ -6,10 +6,16 @@
- Be able to understand English
- Be able to understand the language you want to translate riot-web 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 performig the translation (which must still be performed separately, and after the translation system has been initialized).
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: "performig"

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be useful to provide a small code-snippet example of a string being defined as a module constant, and then later translating at the point of rendering.


Basically, whenever a translatable string is introduced, you should call either `_t()` immediately OR `_td()` and later `_t()`.

## Adding new strings

1. Check if the import ``import { _t } from 'matrix-react-sdk/lib/languageHandler';`` is present. If not add it to the other import statements.
2. Add ``_t()`` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method)
1. Check if the import ``import { _t } from 'matrix-react-sdk/lib/languageHandler';`` is present. If not add it to the other import statements. Also import `_td` if needed.
2. 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.
3. Add the String to the ``en_EN.json`` file in ``src/i18n/strings`` (respect which repository you are on).

## Adding variables inside a string.
Expand All @@ -21,6 +27,8 @@

## Things to know/Style Guides

- Do not use it inside ``getDefaultProps`` at the point where ``getDefaultProps`` is initialized the translations aren't loaded yet and it causes missing translations.
- If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded.
- Do not use `_t()` inside ``getDefaultProps`` at the point where ``getDefaultProps`` is initialized when the translations aren't loaded yet and it causes missing translations. Use `_td()` instead and perform the actual translation later.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can I suggest, "Do not use _t() inside getDefaultProps: the translations aren't loaded when getDefaultProps is called, leading to missing translations. Use _td to indicate that _t will be called on the string later "

- If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded. Mark the strings using `_td()` instead and perform the actual translation later.
- If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
- 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Some very good advice, thanks for this 😃

4 changes: 2 additions & 2 deletions src/components/views/context_menus/RoomTileContextMenu.js
Expand Up @@ -21,7 +21,7 @@ import Promise from 'bluebird';
import React from 'react';
import classNames from 'classnames';
import sdk from 'matrix-react-sdk';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
import { _t, _td } from 'matrix-react-sdk/lib/languageHandler';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import dis from 'matrix-react-sdk/lib/dispatcher';
import DMRoomMap from 'matrix-react-sdk/lib/utils/DMRoomMap';
Expand Down Expand Up @@ -185,7 +185,7 @@ module.exports = React.createClass({
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
dis.dispatch({ action: 'view_next_room' });
}, function(err) {
var errCode = err.errcode || "unknown error code";
var errCode = err.errcode || _td("unknown error code");
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
title: _t('Failed to forget room %(errCode)s', {errCode: errCode}),
Expand Down
1 change: 0 additions & 1 deletion src/i18n/strings/ar.json
Expand Up @@ -20,7 +20,6 @@
"Collapse panel": "طي الجدول",
"Collecting app version information": "إستعادة معلومات النسخة للتطبيق",
"Collecting logs": "إستعادة السجلات",
"Create new room": "إنشاء غرفة جديدة",
"Couldn't find a matching Matrix room": "لا يمكن إيجاد غرفة مايتركس متطابقة",
"Custom Server Options": "إعدادات السيرفر خاصة",
"delete the alias.": "إلغاء المُعرف.",
Expand Down
12 changes: 0 additions & 12 deletions src/i18n/strings/be.json
Expand Up @@ -7,7 +7,6 @@
"Cancel Sending": "Адмяніць адпраўку",
"Can't update user notification settings": "Немагчыма абнавіць налады апавяшчэнняў карыстальніка",
"Close": "Зачыніць",
"Create new room": "Стварыць новы пакой",
"Couldn't find a matching Matrix room": "Не атрымалася знайсці адпаведны пакой Matrix",
"Custom Server Options": "Карыстальніцкія параметры сервера",
"delete the alias.": "выдаліць псеўданім.",
Expand All @@ -16,7 +15,6 @@
"Directory": "Каталог",
"Dismiss": "Aдхіліць",
"Download this file": "Спампаваць гэты файл",
"Drop here %(toAction)s": "Перацягнуць сюды %(toAction)s",
"Enable audible notifications in web client": "Ўключыць гукавыя апавяшчэнні ў вэб-кліенце",
"Enable desktop notifications": "Ўключыць апавяшчэнні на працоўным стале",
"Enable email notifications": "Ўключыць паведамлення па электроннай пошце",
Expand All @@ -26,14 +24,12 @@
"Error": "Памылка",
"Error saving email notification preferences": "Памылка захавання налад апавяшчэнняў па электроннай пошце",
"#example": "#прыклад",
"Failed to": "Не атрымалася",
"Failed to add tag %(tagName)s to room": "Не атрымалася дадаць %(tagName)s ў пакоі",
"Failed to change settings": "Не атрымалася змяніць налады",
"Failed to forget room %(errCode)s": "Не атрымалася забыць пакой %(errCode)s",
"Failed to update keywords": "Не атрымалася абнавіць ключавыя словы",
"Failed to get protocol list from Home Server": "Не ўдалося атрымаць спіс пратаколаў ад хатняга сервера",
"Failed to get public room list": "Не ўдалося атрымаць спіс агульных пакояў",
"Failed to join the room": "Не ўдалося далучыцца да пакоя",
"Failed to remove tag %(tagName)s from room": "Не ўдалося выдаліць %(tagName)s з пакоя",
"Failed to set direct chat tag": "Не ўдалося ўсталяваць тэг прамога чата",
"Failed to set Direct Message status of room": "Не ўдалося ўсталяваць статут прамога паведамлення пакою",
Expand All @@ -42,9 +38,7 @@
"Files": "Файлы",
"Filter room names": "Фільтр iмёнаў пакояў",
"Forget": "Забыць",
" from room": " з пакоя",
"Guests can join": "Госці могуць далучыцца",
"Guest users can't invite users. Please register to invite.": "Госцi не могуць запрашаць карыстальнікаў. Калі ласка, зарэгіструйцеся, каб запрасiць.",
"Invite to this room": "Запрасіць у гэты пакой",
"Keywords": "Ключавыя словы",
"Leave": "Пакінуць",
Expand All @@ -63,7 +57,6 @@
"On": "Уключыць",
"Operation failed": "Не атрымалася выканаць аперацыю",
"Permalink": "Пастаянная спасылка",
"Please Register": "Калі ласка, зарэгіструйцеся",
"powered by Matrix": "працуе на Matrix",
"Quote": "Цытата",
"Redact": "Адрэдагаваць",
Expand All @@ -74,15 +67,10 @@
"Remove from Directory": "Выдалiць з каталога",
"Resend": "Паўторна",
"Riot does not know how to join a room on this network": "Riot не ведае, як увайсці ў пакой у гэтай сетке",
"Room directory": "Каталог пакояў",
"Room not found": "Пакой не знойдзены",
"Search for a room": "Пошук па пакоі",
"Settings": "Налады",
"Source URL": "URL-адрас крыніцы",
"Start chat": "Пачаць чат",
"The Home Server may be too old to support third party networks": "Хатні сервер можа быць занадта стары для падтрымкі іншых сетак",
"There are advanced notifications which are not shown here": "Ёсць пашыраныя апавяшчэння, якія не паказаныя тут",
"The server may be unavailable or overloaded": "Сервер можа быць недаступны ці перагружаны",
"This room is inaccessible to guests. You may be able to join if you register.": "Гэты пакой недаступны для гасцей. Вы можаце далучыцца, калі вы зарэгіструецеся.",
" to room": " ў пакоі"
}
7 changes: 0 additions & 7 deletions src/i18n/strings/ca.json
Expand Up @@ -7,12 +7,10 @@
"Failed to change password. Is your password correct?": "Hi ha hagut un error al canviar la vostra contrasenya. És correcte la vostra contrasenya?",
"Continue": "Continua",
"All Rooms": "Totes les sales",
"Create new room": "Crea una nova sala",
"Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi",
"Failed to add tag %(tagName)s to room": "No s'ha pogut afegir l'etiqueta %(tagName)s a la sala",
"Failed to forget room %(errCode)s": "No s'ha pogut oblidar la sala %(errCode)s",
"Failed to get public room list": "No s'ha pogut obtenir el llistat de sales públiques",
"Failed to join the room": "No s'ha pogut unir a la sala",
"Failed to remove tag %(tagName)s from room": "No s'ha pogut esborrar l'etiqueta %(tagName)s de la sala",
"Filter room names": "Filtra els noms de les sales",
"Couldn't load home page": "No s'ha pogut carregar la pàgina d'inici",
Expand All @@ -22,15 +20,12 @@
"Direct Chat": "Xat directe",
"Directory": "Directori",
"Failed to set direct chat tag": "No s'ha pogut establir l'etiqueta del xat directe",
"Room directory": "Directori de sales",
"Start chat": "Inicia un xat",
"Invite to this room": "Convida a aquesta sala",
"No rooms to show": "No hi ha sales a mostrar",
"Riot does not know how to join a room on this network": "El Riot no sap com unir-se a una sala en aquesta xarxa",
"Room not found": "No s'ha trobat la sala",
"Unnamed room": "Sala sense nom",
"#example": "#exemple",
"Settings": "Paràmetres",
"Failed to change settings": "No s'han pogut modificar els paràmetres",
"Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web",
"Enable desktop notifications": "Habilita les notificacions d'escriptori",
Expand Down Expand Up @@ -85,7 +80,6 @@
"Source URL": "URL origen",
"The server may be unavailable or overloaded": "El servidor pot no estar disponible o sobrecarregat",
"This Room": "Aquesta sala",
" to room": " a la sala",
"Unavailable": "No disponible",
"Unknown device": "Dispositiu desconegut",
"unknown error code": "codi d'error desconegut",
Expand All @@ -110,7 +104,6 @@
"Checking for an update...": "Comprovant si hi ha actualitzacions...",
"No update available.": "No hi ha cap actualització disponible.",
"Downloading update...": "Descarregant l'actualització...",
"Welcome page": "Pàgina de benvinguda",
"Welcome to Riot.im": "Benvingut a Riot.im",
"Chat with Riot Bot": "Conversa amb el Bot de Riot"
}
14 changes: 0 additions & 14 deletions src/i18n/strings/cs.json
Expand Up @@ -4,10 +4,6 @@
"A new version of Riot is available.": "Je dostupná nová verze Riotu.",
"Notifications": "Upozornění",
"Search": "Hledání",
"Settings": "Nastavení",
"Create new room": "Založit novou místnost",
"Room directory": "Adresář místností",
"Start chat": "Začít chat",
"All Rooms": "Všechny místnosti",
"Files": "Soubory",
"Filter room names": "Filtrovat místnosti dle názvu",
Expand All @@ -30,10 +26,8 @@
"Error": "Chyba",
"Failed to change settings": "Nepodařilo se změnit nastavení",
"Failed to get public room list": "Nepodařilo se získat seznam veřejných místností",
"Failed to join the room": "Vstup do místnosti se nezdařil",
"Favourite": "V oblíbených",
"Guests can join": "Hosté mohou vstoupit",
"Guest users can't invite users. Please register to invite.": "Hosté nemohou zvát uživatele. Zaregistrujte se a budete moci zvát.",
"Hide panel": "Skrýt panel",
"I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat",
"Keywords": "Klíčová slova",
Expand Down Expand Up @@ -61,7 +55,6 @@
"Please set a password!": "Prosím nastavte si heslo!",
"You have successfully set a password!": "Úspěšně jste si nastavili heslo!",
"Failed to change password. Is your password correct?": "Nepodařilo se změnit heslo. Je vaše heslo správné?",
"Welcome page": "Uvítací stránka",
"No update available.": "Není dostupná žádná aktualizace.",
"Downloading update...": "Stahování aktualizace...",
"Welcome to Riot.im": "Vítá vás Riot.im",
Expand All @@ -72,7 +65,6 @@
"Off": "Vypnout",
"On": "Zapnout",
"Operation failed": "Chyba operace",
"Please Register": "Prosím zaregistrujte se",
"Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?",
"Remove": "Odebrat",
"remove %(name)s from the directory.": "odebrat %(name)s z adresáře.",
Expand Down Expand Up @@ -126,7 +118,6 @@
"Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti",
"Failed to send report: ": "Nepodařilo se odeslat hlášení: ",
"Forget": "Zapomenout",
" from room": " z místnosti",
"(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)",
"In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Kvůli diagnostice budou spolu s tímto hlášením o chybě odeslány i záznamy z klienta. Chcete-li odeslat pouze text výše, prosím odškrtněte:",
"No rooms to show": "Žádné místnosti k zobrazení",
Expand All @@ -142,15 +133,12 @@
"Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.",
"Sorry, your browser is <b>not</b> able to run Riot.": "Omlouváme se, váš prohlížeč <b>není</b> schopný spustit Riot.",
"There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena",
"This room is inaccessible to guests. You may be able to join if you register.": "Tato místnost není přístupná hostům. Je třeba se nejprve registrovat.",
" to room": " do místnosti",
"Unhide Preview": "Zobrazit náhled",
"Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s",
"Uploading report": "Nahrávám hlášení",
"View Decrypted Source": "Zobrazit dešifrovaný zdroj",
"When I'm invited to a room": "Pokud jsem pozván do místnosti",
"World readable": "Viditelné pro všechny",
"You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!": "Riotujete jako host. <a>Zaregistrujte se</a> nebo <a>se přihlašte</a> pro přístup k více místnostem a funkcím!",
"You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí",
"Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).",
"You need to be using HTTPS to place a screen-sharing call.": "Pro uskutečnění hovoru se sdílením obrazovky musíte používat HTTPS.",
Expand All @@ -171,7 +159,6 @@
"Collapse panel": "Sbalit panel",
"Dismiss": "Zahodit",
"Expand panel": "Rozbalit panel",
"Failed to": "Nepodařilo se",
"Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu",
"Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy",
"powered by Matrix": "poháněno Matrixem",
Expand All @@ -198,7 +185,6 @@
"To return to your account in future you need to <u>set a password</u>": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si <u>nastavit heslo</u>",
"This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.",
"You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.",
"Drop here %(toAction)s": "Přetažením sem %(toAction)s",
"Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany",
"Messages in one-to-one chats": "Zprávy v individuálních chatech",
"Notification targets": "Cíle upozornění",
Expand Down