From 00a9f68eea20cf2705f8805e55fece3d5bab79ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yago=20Gonz=C3=A1lez?= Date: Fri, 3 Feb 2017 20:29:24 +0000 Subject: [PATCH] docs: Improve the translation guide. --- docs/translating.md | 212 +++++++++++++++++++++++++++++--------------- 1 file changed, 139 insertions(+), 73 deletions(-) diff --git a/docs/translating.md b/docs/translating.md index 0e3a40ca9d..fee72117f1 100644 --- a/docs/translating.md +++ b/docs/translating.md @@ -1,12 +1,9 @@ # Translating Zulip -Zulip has full support for Unicode, so you can already use your -preferred language everywhere in Zulip. - To make Zulip even better for users around the world, the Zulip UI is being translated into a number of major languages, including Spanish, German, French, Chinese, Russian, and Japanese, with varying levels of -progress. If you speak a language other than English, your help with +progress. If you speak a language other than English, your help with translating Zulip would be greatly appreciated! If you're interested in contributing translations to Zulip, please @@ -14,13 +11,16 @@ If you're interested in contributing translations to Zulip, please chat](https://chat.zulip.org/#narrow/stream/translation), and say hello. And please join the [Zulip project on Transifex](https://www.transifex.com/zulip/zulip/) and ask to join any -languages you'd like to contribute to (or add new ones). Transifex's +languages you'd like to contribute to (or add new ones). Transifex's notification system sometimes fails to notify the maintainers when you ask to join a project, so please send a quick email to zulip-core@googlegroups.com when you request to join the project or add a language so that we can be sure to accept your request to contribute. +Zulip has full support for Unicode, so you can already use your +preferred language everywhere in Zulip. + ## Translation style guides We are building a collection of translation style guides for Zulip, @@ -32,40 +32,25 @@ languages (e.g. what word to translate words like "home" to): * [Russian](russian.html) * [Spanish](spanish.html) -## Setting Default language in Zulip +Please, stick to these while translating, and feel free to point out +anything that should be improved or fixed. New style guides for other +languages are welcome, too. -Zulip allows you to set the default language through the settings -page, in the 'Display settings' section. The URL will be -`/#settings/display-settings` on your realm. +## Translation process -## Translation Resource Files +The end-to-end process to get the translations working is as follows. -All the translation magic happens through resource files which hold -the translated text. Backend resource files are located at -`static/locale//LC_MESSAGES/django.po`, while frontend -resource files are located at -`static/locale//translations.json`. These files are -uploaded to Transifex using `tx push`, where they can be -translated. Once translated, they are downloaded back into the -codebase using `tx pull`. +Please note that you don't need to do this if you're translating; this is +only to describe how the whole process is. If you're interested in +translating, you should check out the +[translators' workflow](#translators-workflow). -## Transifex Config - -The config file that maps the resources from Zulip to Transifex is -located at `.tx/config`. Django recognizes `zh_CN` instead of `zh-HANS` -for simplified Chinese language (this is fixed in Django 1.9). This -idiosyncrasy is also handled in the Transifex config file. - -## Translation Process - -The end-to-end process to get the translations working is as follows: - -1. Mark the strings for translations (see sections for +1. The strings are marked for translation (see sections for [backend](#backend-translations) and [frontend](#frontend-translations) translations for details on this). -2. Create translation [resource][] files using the `./manage.py +2. Translation [resource][] files are created using the `./manage.py makemessages` command. This command will create, for each language, a resource file called `translations.json` for the frontend strings and `django.po` for the backend strings. @@ -80,22 +65,105 @@ The end-to-end process to get the translations working is as follows: - It will not override the value of a singular key if that value contains a translated text. -3. A Zulip maintainer uploads the resource files to Transifex using the +3. Those resource files are uploaded to Transifex by a maintainer using the `tx push -s -a` command. 4. Translators translate the strings in Transifex. -5. With some setup, anyone can download the updated resource files - from Transifex using the `tx pull -a` command. This command will - download the resource files from Transifex and replace your local - resource files with them. +5. The translations are downloaded back into the codebase by a maintainer, + using `tx pull`. -6. One runs `./manage.py compilemessages` to compile the - translation strings so that they are will be used in the Zulip - development environment. This is run automatically during Zulip - development environment provisioning. +## Translators' workflow -## Backend Translations +These are the steps you should follow if you want to help to translate +Zulip: + +1. Join us on Zulip and ask for access to the organization, as + [described](#translating-zulip) at the beginning. + +2. Make sure you have access to Zulip's dashboard in Transifex. + +3. Ask a maintainer to update the strings. + +4. Translate the strings for your language in Transifex. + +Some useful tips for your translating journey: + +- Don't translate variables or code (usually preceded by a `%`, or inside + HTML tags `<...>`). + +- In case of doubt, ask for context in our [developers' Zulip + chat](https://chat.zulip.org/#narrow/stream/translation). + +- If there are multiple possible translations for a term, search for it in + the *Concordance* tool (the button with a magnet in the top right corner). + + It will show if anyone translated that term before, so we can achieve good + consistency with all the translations, no matter who makes them. + +- Follow your language's [translation guide](#translation-style-guides). + Keeping it open in a tab while translating is very handy. + +- Pay attention to capital letters and punctuation. Details make the + difference! + +- Take advantage of the hotkeys the Transifex Web Editor provides, such as + `Tab` for saving and going to the next string. + +## Testing translations + +First of all, download the updated resource files from Transifex using the +`tx pull -a` command (it will require some +[initial setup](#transifex-cli-setup)). This command will download the +resource files from Transifex and replace your local resource files with +them. + +Then, make sure that you have compiled the translation strings using +`./manage.py compilemessages`. + +Django figures out the effective language by going through the following +steps: + +1. It looks for the language code in the url. +2. It looks for the `LANGUAGE_SESSION_KEY` key in the current user's +session. +3. It looks for the cookie named 'django_language'. You can set a +different name through the `LANGUAGE_COOKIE_NAME` setting. +4. It looks for the `Accept-Language` HTTP header in the HTTP request. +Normally your browser will take care of this. + +The easiest way to test translations is through the i18n URLs, e.g., if you +have German translations available, you can access the German version of a +page by going to `/de/path_to_page` in your browser. + +To test translations using other methods you will need an HTTP client +library like `requests`, `cURL` or `urllib`. Here is some sample code to +test `Accept-Language` header using Python and `requests`: + +``` +import requests +headers = {"Accept-Language": "de"} +response = requests.get("http://localhost:9991/login/", headers=headers) +print(response.content) +``` + +## Setting the default language in Zulip + +Zulip allows you to set the default language through the settings +page, in the 'Display settings' section. The URL will be +`/#settings/display-settings` on your realm. + +## Translation resource files + +All the translation magic happens through resource files which hold +the translated text. Backend resource files are located at +`static/locale//LC_MESSAGES/django.po`, while frontend +resource files are located at +`static/locale//translations.json`. + +These files are uploaded to [Transifex][], where they can be translated. + +## Backend translations All user-facing text in the Zulip UI should be generated by an HTML template so that it can be translated. @@ -146,7 +214,7 @@ JsonableError(_('English Text')) To ensure we always internationalize our JSON errors messages, the Zulip linter (`tools/lint-all`) checks for correct usage. -## Frontend Translations +## Frontend translations Zulip uses the [i18next][] library for frontend translations. There are two types of files in Zulip frontend which can hold translatable @@ -220,6 +288,33 @@ The rules for plurals are same as for JavaScript files. You just have to declare the appropriate keys in the resource file and then include the `count` in the context. +## Transifex config + +The config file that maps the resources from Zulip to Transifex is +located at `.tx/config`. Django recognizes `zh_CN` instead of `zh-HANS` +for simplified Chinese language (this is fixed in Django 1.9). This +idiosyncrasy is also handled in the Transifex config file. + +# Transifex CLI setup + +In order to be able to run `tx pull` (and `tx push` as well, if you're a +maintainer), you have to specify your Transifex credentials in a config +file, located at `~/.transifexrc`. + +You can find details on how to set it up [here][transifexrc], but it should +look similar to this (with your credentials): + +``` +[https://www.transifex.com] +username = user +token = +password = p@ssw0rd +hostname = https://www.transifex.com +``` + +This basically identifies you as a Transifex user, so you can access your +organizations from the command line. + [Django]: https://docs.djangoproject.com/en/1.9/topics/templates/#the-django-template-language [Jinja2]: http://jinja.pocoo.org/ @@ -230,34 +325,5 @@ the `count` in the context. [official]: http://i18next.com/translate/pluralSimple/ [helpers]: http://handlebarsjs.com/block_helpers.html [resource]: http://i18next.com/translate/ - -## Testing Translations - -First of all make sure that you have compiled the translation strings -using `./manage.py compilemessages`. - -Django figures out the effective language by going through the -following steps: - -1. It looks for the language code in the url. -2. It looks for the `LANGUAGE_SESSION_KEY` key in the current user's -session. -3. It looks for the cookie named 'django_language'. You can set a -different name through the `LANGUAGE_COOKIE_NAME` setting. -4. It looks for the `Accept-Language` HTTP header in the HTTP request. -Normally your browser will take care of this. - -The easiest way to test translations is through the i18n URLs, e.g., -if you have German translations available, you can access the German -version of a page by going to `/de/path_to_page` in your browser. - -To test translations using other methods you will need an HTTP client -library like `requests`, `cURL` or `urllib`. Here is some sample code -to test `Accept-Language` header using Python and `requests`: - -``` -import requests -headers = {"Accept-Language": "de"} -response = requests.get("http://localhost:9991/login/", headers=headers) -print(response.content) -``` +[Transifex]: https://transifex.com +[transifexrc]: https://docs.transifex.com/client/client-configuration#transifexrc