Translating OpenREM strings
OpenREM’s primary language is British English (en_GB). Users and developers with knowledge of other languages can create translations of the interface strings, export file strings and the documentation. These will then be exposed when the web browser language is set to match the new translation language (OpenREM interface) or when the language is selected for the documentation.
A web-based service for managing translations has kindly been provided to OpenREM by Weblate. Their hosting is free to OpenREM, and they welcome donations.
Translators
Create an account at https://hosted.weblate.org
The OpenREM project is at https://hosted.weblate.org/projects/openrem/
Each page in the Read The Docs documentation (https://docs.openrem.org) is a separate ‘component’ in Weblate, and they have been named ‘RTD document name’. The web interface strings are all in one ‘component’.
Choose a component, and on the next page you can select one of the existing translations which you can review, edit and propose new translation strings.
Once approved, they will be merged in by developers
Creating new language translations
At the component level, you will see an option to create a new translation. This might need to be done for each component individually.
Code syntax in strings
Be careful not to edit code syntax within strings. For example, Python code might be:
Writing study {row} of {numrows} to All data sheet and individual protocol sheets
This is translated into Norwegian Bokmål as:
Skriver studie av {row} av {numrows} til alle datablad og individuelle protokollblader
Notice that the {}
and their contents is unchanged - but may be moved around within the sentence to produce the
correct grammar for the language being used.
Similarly with Django HTML template strings:
Number in last %(day_delta)s days
becomes:
Antall de siste %(day_delta)s dagene
It is essential that the %()s
as well as the string inside the brackets stay intact.
For the RTD translations, there will be Sphinx codes that should be left untranslated, for example:
:ref:`genindex`
Developers
Install pre-requisites
gettext
Linux: sudo apt install gettext
or equivalent for your distribution. For Windows: download
a precompiled binary installer
sphinx-intl
Activate development environment - see Creating a development environment for details - and add the sphinx packages:
$ pip install sphinx
$ pip install sphinx-intl
$ pip install sphinx-argparse
$ pip install sphinx_issues
$ pip install sphinx_copybutton
Update .pot and .po files
Activate the development environment and move to the root of the OpenREM repository - with the docs
folder and
openrem
folder etc:
$ cd docs/
$ mkdir _static
$ sphinx-build -b gettext . _build/gettext/
$ sphinx-intl update -p _build/gettext/
$ cd ../openrem/
$ django-admin makemessages -a --keep-pot
Adding new interface strings for translation
Please refer to https://docs.djangoproject.com/en/2.2/topics/i18n/translation/ for instructions.
In brief, the following will help get you started, but does not cover lazy translations, plurals and many other things!
All the Sphinx/Read The Docs strings are translatable - if a page does not appear in Weblate that is because it has not been configured as a component there yet.
Python code
First, import gettext
from Django:
from django.utils.translation import gettext as _
Then wrap strings to be translated with _()
so
query.stage = "Checking to see if any response studies are already in the OpenREM database"
becomes
query.stage = _(
"Checking to see if any response studies are already in the OpenREM database"
)
The same is done for strings that contain variables. Unfortunately gettext
cannot work with f-strings so we are
stuck with .format()
instead. It is easier to understand how to translate the text though if we use named variables
rather than position based ones, like this:
query.stage = _("Filter at {level} level on {filter_name} that {filter_type} {filter_list}".format(
level=level, filter_name=filter_name, filter_type=filter_type, filter_list=filter_list
))
Remember we cannot assume the grammar of the translated string so try and pass the whole sentence or paragraph to be translated.
Template code
Add the following at the top of the template file, just after any extends
code:
{% load i18n %}
This can be done with inline translations and block translations. For inline,
<th style="width:25%">System name</th>
becomes
<th style="width:25%">{% trans "System name" %}</th>
If there are variables, a block translation is required, for example:
{% if home_config.display_workload_stats %}
<th style="width:12.5%">{% blocktrans with home_config.day_delta_a as day_delta trimmed %}
Number in last {{ day_delta }} days{% endblocktrans %}</th>
<th style="width:12.5%">{% blocktrans with home_config.day_delta_b as day_delta trimmed %}
Number in last {{ day_delta }} days{% endblocktrans %}</th>
{% endif %}
Comments can be added to aid translators, for example:
{# Translators: Number of studies in DB listed above home-page table. No final full-stop in English due to a.m./p.m. #}
{% now "DATETIME_FORMAT" as current_time %}
{% blocktrans with total_studies=homedata.total trimmed%}
There are {{ total_studies }} studies in this database. Page last refreshed on {{ current_time }}
{% endblocktrans %}
Making use of updated strings on local system
Specify the language to build for Sphinx docs, eg for German:
$ sphinx-build -b html -D language=de . _build/html/de
For Django strings:
$ django-admin compilemessages
Incorporating translations into main repo
In the git repository:
$ git remote add weblate https://hosted.weblate.org/git/openrem/web-interface/
Checkout the
weblate\develop
branch as a new local branchPush the branch to Bitbucket
Create a pull request to develop