Opened 5 years ago

Closed 5 years ago

#10398 closed defect (fixed)

Please do not create strings untranslatable with Transifex

Reported by: lunar Owned by: mikeperry
Priority: Medium Milestone:
Component: TorBrowserButton Version:
Severity: Keywords: MikePerry201403R
Cc: mcs, brade Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

In [ https://gitweb.torproject.org/torbutton.git/blob/HEAD:/src/chrome/locale/en/aboutTor.dtd#l26] aboutTor.dtd one can currently find:

<!-- Note to translators: the following 18 entities are used to construct a
   - sentence (either the SP or DDG entities are used, but not both at the
   - same time).   In English, the sentence reads:
   -    Search securely with Startpage.
   - or:
   -    Search securely with DuckDuckGo.
   - The sentence contains two embedded links for "securely" and
   - the search engine ("Startpage" or "DuckDuckGo").
  -->

That's really, really not the way to do it. Isn't there an equivalent to sprintf for
Firefox extensions?

The following strings can't be translated properly with Transifex:

<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Search ">
<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Search ">
<!ENTITY aboutTor.searchSP.search.beforeLink.label "with ">
<!ENTITY aboutTor.searchDDG.search.beforeLink.label "with ">

The ending space is invisible in any graphical translator (e.g. Transifex, our recommended tool for translators). :(

Child Tickets

Change History (11)

comment:1 Changed 5 years ago by mikeperry

Cc: mcs brade added

comment:2 Changed 5 years ago by mikeperry

Assembling this string dynamically should be possible, but I think that means we will have to invalidate existing translations and convert these to properties instead of DTD elements. It may also require Javascript running in about:tor to do this, though we may be able to assemble the strings in Torbutton and inject them.

If we end up needing to inject them anyway, I suppose an extreme hack might be to create a hidden XUL element with the DTDs in it, extract the elements they are contained in, and reassemble them in JS, and then inject that into about:tor. That will require us to invalidate less strings (perhaps only the ones with spaces), but it might be a little crazy and messy.

comment:3 Changed 5 years ago by lunar

You should invalidate them anyway:

torbutton$ git grep beforeLink.label -- src/chrome/locale | grep -vE '(with|Search)'
src/chrome/locale/de/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Suche">
src/chrome/locale/de/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Suche">
src/chrome/locale/de/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "mit">
src/chrome/locale/de/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "mit">
src/chrome/locale/es/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Busque">
src/chrome/locale/es/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Busque">
src/chrome/locale/es/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "con">
src/chrome/locale/es/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "con">
src/chrome/locale/fa/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "جستجو">
src/chrome/locale/fa/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "جستجو">
src/chrome/locale/fa/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "">
src/chrome/locale/fa/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "">
src/chrome/locale/fr/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Rechercher">
src/chrome/locale/fr/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Rechercher">
src/chrome/locale/fr/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "avec">
src/chrome/locale/fr/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "avec">
src/chrome/locale/it/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Cerca">
src/chrome/locale/it/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Cerca">
src/chrome/locale/it/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "con">
src/chrome/locale/it/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "con">
src/chrome/locale/ja/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "検索">
src/chrome/locale/ja/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "検索">
src/chrome/locale/ja/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "一緒に">
src/chrome/locale/ja/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "一緒に">
src/chrome/locale/ko/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "">
src/chrome/locale/ko/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "">
src/chrome/locale/ko/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "">
src/chrome/locale/ko/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "">
src/chrome/locale/nl/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Zoeken">
src/chrome/locale/nl/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Zoeken">
src/chrome/locale/nl/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "met">
src/chrome/locale/nl/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "met">
src/chrome/locale/pl/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Szukaj">
src/chrome/locale/pl/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Szukaj">
src/chrome/locale/pl/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "z">
src/chrome/locale/pl/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "z">
src/chrome/locale/pt/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Procurar">
src/chrome/locale/pt/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Procurar">
src/chrome/locale/pt/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "com">
src/chrome/locale/pt/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "com">
src/chrome/locale/ru/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "Поиск">
src/chrome/locale/ru/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "Поиск">
src/chrome/locale/vi/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "">
src/chrome/locale/vi/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "">
src/chrome/locale/vi/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "">
src/chrome/locale/vi/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "">
src/chrome/locale/zh-CN/aboutTor.dtd:<!ENTITY aboutTor.searchSP.privacy.beforeLink.label "搜索">
src/chrome/locale/zh-CN/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.privacy.beforeLink.label "搜索">
src/chrome/locale/zh-CN/aboutTor.dtd:<!ENTITY aboutTor.searchSP.search.beforeLink.label "引擎">
src/chrome/locale/zh-CN/aboutTor.dtd:<!ENTITY aboutTor.searchDDG.search.beforeLink.label "引擎">

They are all missing the spaces.

comment:4 Changed 5 years ago by mcs

We did not realize/think about the fact that Transifex would make it impossible to see the spaces. We followed the kind of scheme Mozilla uses for similar text within the Firefox about box, e.g.,

http://mxr.mozilla.org/mozilla-esr24/source/browser/locales/en-US/chrome/browser/aboutDialog.dtd#20

(they also use trailing spaces).

The easiest fix is to move the spaces into aboutTor.xhtml and remove them from the localization process. It is possible for some locale that a space between the pieces would not be desirable, but I don't know of a real world example. The advantage of this solution is that we can probably keep all of the existing translated strings.

Another approach would be to use more of the sprintf approach as lunar suggested. We could have a property string something like this:

aboutTor.searchSP.privacy=Search <a href="%1$S">securely</a> with <a href="%2$S">Start Page</a>.

The strings for %1$S and %2$S would come from localizable properties as well, e.g.,

aboutTor.searchSP.privacy.link=https://startpage.com/eng/protect-privacy.html
aboutTor.searchSP.search.link=https://startpage.com/

This would still give translators control over the order of items within the final string, etc. with the downside that the existing entities would need to be thrown out. Also, translators would have to preserve the HTML tags and balance quoting within the one string, which is very fragile.

comment:5 Changed 5 years ago by brade

We also noticed that in some of the translations have "&amp;nbsp;" in aboutTor.dtd instead of "&nbsp;" or "&#160;". This causes ;nbsp& to show up on the Arabic about:tor page.

This is one of the affected entities: aboutTor.searchSP.privacy.afterLink.label

The following localizations have the problem:

ar de es fa fr it ja nl pl pt ru zh-CN

comment:6 in reply to:  4 Changed 5 years ago by brade

Lunar, Mike: Which of the approaches described in mcs should we use? Do either of you have a better idea?

comment:7 Changed 5 years ago by lunar

A full string with placeholder is how to do it right in my view.

comment:8 Changed 5 years ago by mcs

Status: newneeds_review

Kathy and I committed a fix for this on our bug10398 branch, here:

https://gitweb.torproject.org/user/brade/torbutton.git/commit/54c8721acf3c52855405c669ebfbdbeead69806a

We did our best to preserve the existing translated strings, converting
them to the new scheme and adding the missing spaces.

Mike -- you will also need to update the trans_tools/import-translations.sh script once the new aboutTor.properties file has been added to the translation repo.

comment:9 Changed 5 years ago by qbi

Also discussed in #10561

comment:10 Changed 5 years ago by mikeperry

Keywords: MikePerry201403R added

Feel free to tag any tickets that are ready for review+merge with MikePerry2014MMR, so I can easily find them while merging things for a given release.

comment:11 Changed 5 years ago by mikeperry

Resolution: fixed
Status: needs_reviewclosed

Merged. There were some conflicts, but I think I resolved them. I hope the translations still make sense..

Note: See TracTickets for help on using tickets.