-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Strings and Localization
Most strings are provided as resources, so that they may be translated to the many languages that Brave supports.
They can be split in to two categories: those that are provided and referenced only from Brave code, and those that are provided and referenced from within Chromium code.
All brave-only strings are referenced from one of the files listed in lib/l10nUtil.js
in braveNonGeneratedPaths
.
Modifications and additions should be made directly to one of the files listed there. Translated versions of modified or added strings will only happen once per release cycle.
No action necessary. Original and translated strings from chromium src .grd, .grdp and .xtb files are used in-place.
For each chromium release, the chromium GRD and GRDP files that we wish to make modifications to are copied to a file inside the brave-core source. Some mappings include:
Chromium path | Brave path |
---|---|
chrome_app_chromium_strings.grd | app/brave_strings.grd |
chrome_app_generated_resources.grd | app/generated_resources.grd |
chrome_app_bookmarks_strings.grdp | app/bookmarks_strings.grdp |
- If the GRD or GRDP is not yet present by Brave-Core:
- Add a path to
brave-browser/lib/l10nUtil.js
- Add an entry to
chromiumToAutoGeneratedBraveMapping
map - Add a mapping to
get_original_grd
function inbrave/script/lib/transifex.py
- Add a path to
- Add any whole-file string replacement rules to the
rebaseBraveStringFilesOnChromiumL10nFiles
function- Add any specific xml transforms to
chromium-rebase-l10n.py
- Add any specific xml transforms to
- In Brave-Browser, run
npm run chromium_rebase_l10n
- This will output a new or modified .grd[p] file which should be committed.
-
_override.grd
files are generated automatically (please don't make edits to them). There are a series of regex replacements done (ex: Chrome => Brave) and these_override.grd
files will get overwritten each time.
The modified string will then get translated when the next release train visits the localization station!
Modifying English source strings in GRD files will invalidate all translations of that string, since the translations reference the original string hash. All users will then only see the English fallback string until the next translation process is performed during a release cycle.
These are .xtb files containing xml elements of the form:
<translation id=“[number]”>[Translated Text]</translation>
The Translation ID refers to the unique fingerprint of the original string as it appears in the source GRD file. This means that multiple strings that have the exact same English value in the source GRD file will only get translated once per language per GRD file.
Strings are matched using filename (not path). This is something we control in transifex.py. Within each file, each unique string from a GRD is translated and pulled down. It is then stored in a corresponding .xtb file with the translation ID (unique fingerprint of the original string).
- Provide a descriptive
desc=“”
attribute on each<message
attribute informing the translator of the context for the string.- Mention if it should be title case or not
- Specify which Proper Nouns should not be translated.
- Use
translateable="false"
if the whole string should not be translated. - Use
<if expr=“”>
to inform the compiler which string to select. This is useful for platform variations or platform-specific strings. For example:- Strings that should have a different case on different systems such as title-case for macOS menus and lower-case for menus on other platforms (
<if expr="use_titlecase">
) - Strings that only appear on a single platform, such as Android (
<if expr="is_android">
)
- Strings that should have a different case on different systems such as title-case for macOS menus and lower-case for menus on other platforms (
- Login to Transifex and navigate to the Brave dashboard https://www.transifex.com/brave/brave/dashboard/
- Click
Order
- You can pick from 3 providers gengo, TextMaster, and e2f
- We use e2f.
- Select something like Technical and Software for the "Tone". This screen also allows you to write information to the localizer. Simply put this in that box:
Please read this!
https://github.com/brave/brave-browser/wiki/Information-for-localizers
- Press Next and it should take a minute or two to load, I think this happens because we have a lot of strings.
- Uncheck
All
, then only select these resources for translation, the rest are taken from Chromium but we just store them in Transifex:-
android_brave_strings
, -
brave_components_resources
, -
brave_extension
, -
brave_generated_resources
, and - all
*_override
files. - Leave the rest unchecked!
-
- The officially supported (by Chromium) languages are:
af, am, ar, as, az, be, bg, bn, bs, ca, cs, cy, da, de, el, en-GB, en, es, es-419, et, eu, fa, fi, fil, fr-CA, fr, gl, gu, he, hi, hr, hu, hy, id, is, it, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt-BR, pt-PT, or, ro, ru, si, sk, sl, sq, sr-Latn, sr, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-HK, zh-TW, zu
- Here are the 49 languages we currently select to order (same as bolded items in the above list):
# e2f
Amharic (am)
Arabic (ar)
Bengali (bn)
Bulgarian (bg)
Catalan (ca)
Chinese-CN (zh-CN)
Chinese-TW (zh-TW)
Croatian (hr)
Czech (cs)
Danish (da)
Dutch (nl)
English-GB (en-GB)
Estonian (et)
Filipino (fil)
Finnish (fi)
French (fr)
French-CA (fr-CA)
Galician (gl)
German (de)
Greek (el)
Hebrew (he)
Hindi (hi)
Hungarian (hu)
Indonesian (id)
Italian (it)
Japanese (ja)
Kannada (kn)
Korean (ko)
Latvian (lv)
Lithuanian (lt)
Malay (ms)
Norwegian (no)
Persian (fa)
Polish (pl)
Portuguese-BR (pt-BR)
Portuguese-PT (pt-PT)
Romanian (ro)
Russian (ru)
Serbian (sr)
Slovak (sk)
Slovenian (sl)
Spanish (es)
Spanish-LA (es-419)
Swahili (sw)
Swedish (sv)
Thai (th)
Turkish (tr)
Ukrainian (uk)
Vietnamese (vi)
- The total cost is usually in the hundreds to thousands range, but usually below 10k. If it's above 10k then please get special approval and make sure everything is being selected correctly.
This information can now be found here
For Desktop, the ideal time to submit an order would be 1 week before the release. Per the release schedule, this lines up with the migration date. We have submitted orders with 4 days left before a release, but that's very tight. The translations themselves take a while to complete.
When it's time to submit, we typically have the PR that contains the uplift of the target Chromium version into the Release branch (or, Beta branch, if the channel migration has not run yet). We submit the strings from that branch. If the uplift has already been merged into the Release (Beta - before the migrations) branch, then we submit from that branch directly, instead of the PR branch. Once the translations have been completed, we pull them into the Release branch and then look at back-porting the strings into other branches. If release channel is 1.2 and nightly is 1.4, we'd create "lowering" PRs for 1.3 and 1.4 with the string changes from 1.2.
Once translations are ordered, we should make every effort to NOT make string changes to the product. The strings in the product should be considered frozen by reviewers.
Run this to push new strings to Transifex. The script can also push up translations, if needed (see command line params). If you need access to Transifex talk to devops.
To run these command you will need Python3 (3.10.x) with the following modules:
- lxml
- transifex-python==2.1.0
npm run push_l10n
Run this to pull down new xtb and translation files:
npm run pull_l10n
Do a commit for all the string translation updates (message.json
and/or xtb
files).
These steps should be done any time we have new strings and any time we rebase on top of MetaMask.
Pushing changes to Transifex:
npm run push_l10n -- --extension=ethereum-remote-client
Pulling changes from Transifex:
npm run pull_l10n -- --extension=ethereum-remote-client
A rule for developing w/ strings for this extension: Never change a MetaMask source string text, instead change the l10n ID that's being used and add the string into brave/app/_locales/en/messages.json
The official supported locales are the same as in Brave and are listed above here: https://github.com/brave/brave-browser/wiki/Strings-and-Localization#information-for-submitting-localization-orders When making an order you want to select both of these projects:
ethereum_remote_client_extension
brave_ethereum_remote_client_extension
Note, they don't fully match the list from MetaMask.
MetaMask supports hn
, ht
, and ph
that Brave does not.
This is changing but it uses tml
for ta
as well.