-
Notifications
You must be signed in to change notification settings - Fork 140
l10n guide
We use traditional gettext-style localization, split in two repos.
Added in https://github.com/ansible/galaxy_ng/pull/882
We're using a _() function, parameters are fine as long as the format string gets passed through _() before interpolation. (That makes python f-strings unsuitable for l10n without modification.)
Do translate error messages in API responses, don't translate log messages.
+from django.utils.translation import gettext_lazy as _
- errmsg = 'Repository "{pulp_id}" not found while creating synclist'
+ errmsg = _('Repository "{pulp_id}" not found while creating synclist')
raise ValidationError(errmsg.format(pulp_id=repository_id))
except IntegrityError as exc:
- raise ValidationError("Synclist already exists: %s" % exc)
+ raise ValidationError(_("Synclist already exists: %s") % exc)String extraction can be triggered using django-admin makemessages (podman exec -it galaxy_ng_api_1 pulpcore-manager makemessages), this creates the .po files, then, those can be compiled to .mo using django-admin compilemessages. All these files live in ./galaxy_ng/locale/*/LC_MESSAGES/.
More details in django translation docs.
Added in https://github.com/ansible/ansible-hub-ui/pull/810
We're using a t`...` template string javascript-side, and a <Trans> component for React JSX.
Current language is autodetected based on browser settings, and compared with the list of availableLanguages in src/l10n.js.
(It may be easier to install https://chrome.google.com/webstore/detail/locale-switcher/kngfjpghaokedippaapkfihdlmmlafcc for switching.)
import { t } from '@lingui/macro';
const data = "untranslated";
const string = t`Hello ${data}`;(translators will see Hello {data}, translate to something like Hola {data} resulting in Hola untranslated in the UI)
❗ Prefer using variables in string substition: t`Hello ${data.data}` is using an expression, not a simple variable, so the translators will see Hello {0}, they won't know what {0} means without context.
import { Trans } from '@lingui/macro';
const data = "untranslated";
const MyComponent = () => (
<Trans>Hello <b>World</b>: {data}</Trans>
);(translators will see Hello <0>World</0>: {data}, translate to Hola <0>mundo</0>: {data} resulting in Hola mundo: untranslated)
import { plural } from '@lingui/macro';
const myCount = 123;
const string = plural(myCount, {
one: '# byte',
other: '# bytes',
}); // yields 0 bytes, 1 byte, 2 bytes, ... depending on myCount(translators will see {myCount, plural, one {# byte} other {# bytes}}, translate to something like {myCount, plural, one {# byt} few {# byty} other {# bytů}}, yielding 0 bytů, 1 byt, 2 byty, ..., 5 bytů depending on myCount)
More details in lingui docs; prefer the macro version for consistency.
- run
gettext:extractto extract translatable strings fromsrc/intolocale/*.po - those
*.pofiles get uploaded to a translation service (outside automation) - updated
*.pofiles get downloaded from the service and merged in (usemsgmergeto resolve conflicts if necessary) - run
gettext:compileto createlocale/*.jsfiles for eachpocounterpart - webpack automatically builds each locale js into a separate bundle
- using a dynamic import in
src/l10n.tsto import the right one at runtime
Sponsored by Red Hat, Inc.