-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i18n support #29
Comments
I would be very keen to add localization to Trizbort. The application doesn't have a vast amount of localizable text, so it should be little effort to translate. Later on, it will enable other contributors to add translations over time, without having to touch the actual code. I am happy to see development of a TypeScript implementation of this, so it'll be easy to drop in. In particular I like "simple" implementations: it is immediately clear how this should be used. I do find accessibility an important feature. This is why Trizbort has (some) keyboard support, and localization is also part of accessibility. A couple of questions about rosetta-typescript: Resource file formatIs there a reason why the message JSON format is this:
rather than this:
I figure it has to do with some standard, but I'm curious to know. Language switchingI thought it might be nice to be able to switch languages on the fly, rather than opening a new URL. This seems to be rather more of a change to Trizbort than to any translation library; it would have to re-render the GUI with new text, while keeping the user's map open. On the other hand, this is probably a feature that no one would ever use. Once a user picks a language, they're likely to stick with it, I suppose. Perhaps this may be a consideration for your project? DependenciesThere were a few design goals when I starting building Trizbort:
Clearly rosetta-typescript could be compiled into Trizbort and require no additional download. On the other hand, the language files will be additional downloads (well, just one). I suppose it will be retrieved through AJAX from the server, after Trizbort first loads. Do I have that right? |
Also see #30 for a use case where localization would add a lot of value. |
Ok. I'll try to briefly answer your questions before I endeavor on my daily lunch hike 😄 Resource file format I chose the format specifically because it's already being used by Chrome Apps and WebExtensions in general. Furthermore, as noted before, it's well supported by leading online translation platforms. Language switching I thought about that, and it would certainly be a possibility. During window initialization I simply set the Homepage: "index.html?lang=" + i18n.GetUILanguage(), Dependencies The current implementation utilizes the Fetch API The following code is what this boils down to (where import { Translations } from './types';
export default function load(locale: string): Promise<Translations> {
const url = `locales/${locale}/messages.json`;
return fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(
`${response.status}: Could not retrieve file at ${url}`
);
}
return response.json();
});
} |
Ok. For the TS version of the library I've created a slight divergence from the Chrome i18n reference. I've added the following method setUILanguage(locale: string): Promise<void> This accepts any one locale string and, unless rejected (i. e. in the case of an unsupported language), loads the new language and replaces all existing message strings. That should deal with your Language switching question gracefully. |
I just finished the initial implementation this morning (minus the desktop app specific parts). The source code can be found here Any key prepended with For translation tracking I chose Transifex. Eventually I plan moving Rosetta into its own distinct git repository and publish it to npm. DemoEnglishhttps://pedantic-heyrovsky-f84015.netlify.com Germanhttps://pedantic-heyrovsky-f84015.netlify.com/?lang=de# One more implementation detail that will probably change over time: Currently, strings that are untranslated will show up as their keys for that respective language. |
Great stuff! I had a look at the code just now. It'll be interesting to add this to Trizbort, too. I am unsure what Transifex does, exactly. Is that where I would go if I wanted to contribute translation strings? |
Exactly. Transifex is my chosen translation platform (you could also pick Crowdin or any other solution. I just found Transifex the easiest one to set up). Transifex is where you translate strings and add new languages, whereas all the source strings are defined locally (inside This is the translation workflow, in a nutshell:
|
I also added a short write-up about it to my blog: https://happy-ferret.github.io/posts/yggdrasil-announcement.html I've got a busy week ahead of me, but I'm positive I can wrap up Yggdrasil v0.3.0 by the end of the first week of September. Once that is done, I'll work on a patch for trizbort.io adding the same functionality to it. |
You leave me no choice but to sign up for Transifex to provide you with Dutch and Portuguese translations. A language request should be coming in momentarily. |
I didn't follow everything but count me on to translate it in French. |
@Selsynn Translations are for Yggdrasil, a fork of Trizbort, and they're done in Transifex (sign up there -- see messages above). @Happy-Ferret will need to accept your French language request. We may be able to move any translations back to Trizbort later. |
Cool! I'll make sure to add more keys over the coming days. So far, I think I've only added translation keys for the main menu panel and the dialogues. |
Ah. I see you already figured out how to request new languages 😺 |
In the future I'll probably add "description" fields to the source strings, to make it easier to actually locate a language string/make sense of it. |
@Happy-Ferret You'll still need to accept our joining the various translation groups on Transifex. |
@henck Strange. I don't see any requests, and I can't invite you by username somehow. |
Ah! Found it. Was under "Teams" rather than general notifications. |
Confirmation received. |
OK, Dutch and Portuguese fully translated. Be sure to add new keys and give me a heads-up. I have found that there is a Spanish group using Trizbort.io to create JSON maps that they then parse into a format needed for their project, using a custom Python script. They might appreciate a Spanish translation of Trizbort.io/Yggdrasil, as well. |
I just updated the source strings, @henck and @Selsynn. There now translations for the |
I can see the new strings. However, I don't understand which entries should be capitalized. The ones with keys starting with |
Could it be that You Mean Capitalized rather than CAPITALIZED ? |
Exactly. Every single word should start with a capital letter. i. e. "New Map", "Load Map", "Save As Image", etc. |
OK, all done. |
Thanks! I'll review/merge the translations during my lunch break, then (hopefully) add the final source strings by the end of the day. Shouldn't be that many left, and after that I can finally go back to cherry-picking some patches off of Trizbort.io and work on the i18n patch for Trizbort.io. |
Pushed another large update. I think the only ones missing from my version are now the Sorry for the many duplicates. In the future, I'll probably shrink those down to one common key. In the meantime, you can probably just use Transifex' Translation Memory feature to (semi-)automatically translate those duplicates. |
I've enabled Translation Memory for the entire project now, so all remaining, untranslated strings are unique and indeed without a previous translation. |
OK, all done for Dutch and Portuguese. I would like to note that the Initial Caps formatting looks a bit strange in Dutch; I don't know if Microsoft enforces it for their Dutch language products, but I've followed your specification. |
I have some trouble with the difference between Bring to the front/Bring forward, so I will wait to see on the app before trying to translate it |
Hey, @Selsynn. You can already test that feature in the web version. It's part of the element's (room, block and note all support it) popup. Simply place a couple rooms, click one of them and choose the option from the menu (see screenshot). https://pedantic-heyrovsky-f84015.netlify.com/# @henck |
@Happy-Ferret thx I will do the last of the translation tomorrow morning or this evening when i am at home. |
Added the final source strings. 🏎 |
... and done. |
Awesome! FYI. I already started prototyping code for v0.4.0 of Yggdrasil, which will include Chrome OS support. Interestingly, Rosetta-TS works out of the box. It's using the |
Do you need any help with the remaining translations? |
@Happy-Ferret Just needed a reminder that i didn't finish it. Will do it right now. |
This isn't a bug report or a feature request. More of a general inquiry or an RFC (in fact, I'd love to debate some implementation details).
I was wondering what your stance on i18n (internationalization. In this instance, a focus on localization specifically) was.
Is this something you'd like to see supported in the foreseeable future?
I currently work on a set of simple i18n libraries for both Go and TypeScript (aptly dubbed Rosetta-Go and Rosetta-TS, respectively).
Both libraries follow the Chrome i18n API (just the basics, so far. No placeholder support, yet).
In its most basic incarnation there's a
locales
directory. Inside thatlocales
directory are folders named for language shortcodes (en
,fr
,de
, etc. So far, no support for country-specific shortcodes). Inside each of these folders is amessages.json
file that adheres to the following basic pattern (where "new_map_title" and "new_map_text" are unique keys, and the contents of the "message" fields the language-specific display text):To quickly switch between languages in the browser, the user may provide a
lang
argument (i. e.www.trizbort.io/app/index.html?lang=fr
— orwww.trizbort.io/app/index.html?map=hobbit&lang=fr
, to load a new map while also switching the language to French).If a language code is not recognized, the application will launch with the default fallback language (English, for Trizbort) instead. Although here one may also consider checking the browser language (
window.navigator.language
) against the array of supported languages.Both i18n libraries will provide a
GetMessage(key: string)
method to place a translation.The translation specific code for the screenshots below looks as follows:
The beauty of utilizing Chrome i18n lies in its simplicity, as well as the compatibility with most online translation providers like Transifex or Crowdin.
Screenshots: A first WIP implementation running in my fork.
The text was updated successfully, but these errors were encountered: