Translations - Gary-Community-Ventures/benefits-api GitHub Wiki
Translations
MFB is translated into over 10 languages. In order to speed up development Google Translate is used to quickly translate content automatically.
Admin
The translations admin is where text can be created, updated, and translated. Additionally, this is where translations for programs is managed. To access the translations admin go to Django admin, and select the "Translations API" from the sidebar.
Creating a translation
To create a new translation click "Translations" in the side bar, and then click "Add New" in the top right.
You will be prompted to fill out 2 fields:
Label
: a unique key used to identify the translation. Formats vary, but you can use dots to separate groups. e.x.landingPage.links.privacyPolicy
.Default message
: The English text that you would like to be translated.
Once you have filled out those fields, click submit and the translation will be created for you.
Finding a translation
On the "Translations" page there are 2 ways of finding a specific translation.
- If you know the label of the translation you can look it up in the "Search label" box.
- You can search by typing part of the English text into the "Search saved text" box.
Updating a translation
Once you have found the translation that you would like to edit, you can edit it by clicking "Go to" and then clicking "Edit"
Updating meta data
The following meta data can be updated:
Label
: a unique key used to identify the translation. Formats vary, but you can use dots to separate groups. e.x.landingPage.links.privacyPolicy
.Active
: if a translation is active than it will be included in the list of translations sent to the front end.No auto
: Google Translate will not be automatically used if this is selected. This is useful for links where there may be a link to a different page in the selected language, but Google Translate might translate the link incorrectly.
Once the meta data has been updated, click "Save" to save your changes.
The "Save" button under the meta data will only save the meta data
The translation can also be deleted with the red "Delete" button. Deletion will fail if the translation is attached to a program
Updating text
MFB uses Google Translate to quickly create translations. Other languages are automatically translated from English when the translation is created. However, Google Translate does not always give the most ideal translations, so MFB provides a way to override the translated text.
To update a specific language:
- Find the text box with the language code that matches the language you want to update
- Type in the updated text.
- Click on the "Save" button bellow the box.
To restore the original translation click on the "Translate" button and then "Ok" when the pop up shows up.
If you want to update the English text, update the text in the "en-us" box, and then click "Save All". This will Automatically update all of the translations to be translated from the new text instead (unless the "No auto" is selected).
Development
Best practices
Some things that are true about English might not apply to other languages. Here are some things that other languages might do differently from English:
- Have different punctuation
- Have a different order of words. e.x. some languages might have the verb before the noun
- Have different formal and informal words
- Have handle plural words differently
- Have different numbers
Furthermore, because of the way that Google Translate works, it is not possible to translate interpolated strings. For example, you can not translate "he is 30 years old" as one message because the age could change depending on user input. Therefore, you would have to split it into 2 translations of "he is " and " years old". This is unideal because Google Translate does not have all the context it needs to make a translation.
Because of these things here are some best practices:
- Don't apply any text transformations (like splitting text at a punctuation mark) to translated text besides for upper and lower case.
- Include punctuation and spaces in the translation. e.x. If you want to translate "People: [people_count]" include "People: " in the translated message.
- Wrap dynamic numbers with the function returned from the
useTranslateNumber
hook. e.x.const translateNumber = useTranslateNumber();
and then you can usetranslateNumber('$12.34/month')
(There is also a non hook version that takes the locale as a param if you need it). - Don't reuse labels. If the same text appears in two different spots, use 2 different translations (except for select menu items, and displaying which menu item is selected, because we want those to always be in sync).
Frontend
MFB relies on react-intl to use translations.
Here are the 2 main ways to use a translation:
<FormattedMessage id="[label]" defaultMessage="[default_message]" />
const intl = useIntl();
thenintl.formatMessage({id: "[label]", defaultMessage: "[default_message]"});
Don't forget to add the defaultMessage
because it lets the app continue to run if fetching the translations fails.
On the results page, the programs will have attributes (like program.description
) that contain translations with the following structure:
{
"label": "[label]",
"default_message": "[default_message]",
}
The <ResultsTranslate translation={[results_translation]} />
component can be used for translations in the above structure on the results page.
Backend
MFB uses django-parler to handle translations.
To access a translation on the backend follow these steps:
translation = Translation.objects.get(label="[label]")
: get the translation with the labeltranslation.get_lang([language_code])
: get the language for that specific translation.Screen.get_language_code()
can be used to get the language code on theScreen
model.translation.text
: get the string of text for the selected language.
Export translations
MFB provides 2 scripts to copy translations from one environment to another.
python manage.py bulk_export > path/to/file.json
will output a JSON blob that is used to import the translations to another environment.
python manage.py bulk_import < path/to/file.json
will take the JSON blob and use it to add the new translations in the exported JSON blob.
Of course you would want to run these commands in different environments. Here is and example of how to export a translation from Heroku and import it into your dev environment:
heroku run -a cobenefits-api python manage.py bulk_export > dump.json
You will need to delete the last line in the JSON file as Heroku adds an extra character to the output of the command.
python manage.py bulk_import < dump.json
MFB has a repo that contains a history of translations. This means that you do not have to export the translations yourself most of the time. Instead you can pull the latest changes from mfb-translations and use the file with the most recent date (or whatever date you want) to import the translations. i.e. python mange.py bulk_import < ../mfb-translations/translations/[yyyy_mm_dd].json
Brief technical overview
- Translation logic can be found in the translations app
- Translations use django-parler under the hood
- translations/models.py has some useful methods when programmatically creating, updating, or retrieving translations
- Admin frontend code is in translations/templates and translations/static
- Admin backend code is in translations/views.py
- The
python manage.py bulk_translate
command can be used when adding a new language to translate every translation to the new language - The active languages are controlled by
LANGUAGES
in benefits/settings.py