Menu

Hard time understanding String Translation

2014-06-18
2014-06-19
  • aayush chhabra

    aayush chhabra - 2014-06-18

    Hey,

    I am working towards the internationalization of one of my projects, and I am having a real hard time in understanding the way string translation works (date, currency and numbers are good otherwise). Could you please post a simple example of string translation. I have my own JS files and I wanna create a resource bundle and include it in my files.

    Thanks.

     
  • Edwin H

    Edwin H - 2014-06-19

    Hi Aayush,

    Translation is pretty straight-forward. Let's say you have the following Javascript code in your app/web page.

    var rb = new ilib.ResBundle();
    var template = rb.getString("Welcome back, {username}.");
    var str = template.format({username: user.givenName});
    

    Then, you can extract all strings using something like grep and put them into a json object where the properties are the English source strings, and the values are the translations, like this:

    {
        "Welcome back, {username}.": "Welcome back, {username}."
    }
    

    Then, get this file translated by professional translators. They only need to translate the values, not the property names. Here would be the translated German example:

    {
        "Welcome back, {username}.": "Willkommen zurück, {username}."
    }
    

    BTW - one of the things to do in the backlog is to create a string extraction tool that would scan your source code for strings and then write out this json file automatically. Let us know if you want this tool sooner rather than later.

    Now, there are two ways you can get this translation into your app or web page. You can assemble them directly into your javascript, or you can load them dynamically.

    Pre-assembled

    To include the translations directly, you would make a structure like this somewhere at the top of your javascript:

    ilib.data.strings_de = {
        "Welcome back, {username}.": "Willkommen zurück, {username}."
    };
    

    All strings should go under ilib.data with a property named "strings_" plus the ISO code of the language (or locale -- more on that in a minute.) The resource bundle object will check inside of ilib.data for pre-assembled strings and load them first.

    Now let's say the Swiss translator thinks that most of the strings in the German translation are fine, but one of them should be translated a little differently for Swiss German. Then, you might have:

    ilib.data.strings_de = {
        "sentence 1": "Satz 1",
        "Welcome back, {username}.": "Willkommen zurück, {username}.",
        "sentence 2": "Satz 2"
    };
    ilib.data.strings_de_CH = {
        "Welcome back, {username}.": "Willkommen wieder, {username}."
    };
    

    If the current locale is "de-CH", the resource bundle class will first load the strings with the suffix "_de", and then override them with any strings it finds in the object with the suffix "_de_CH". In this way, most of the strings in German which are shared amongst all of the variations of German can go into "_de" (in this example, "sentence 1" and "sentence 2"), and only the strings which are specific to Swiss German need to appear in the object with the "_de_CH" suffix.

    In fact, you can have a whole host of strings for different locales. You can have strings that are specific to a locale with a particular script, or strings that are particular to a country if you need it. Just add the right underscore-separated locale components as a suffix to the "strings" part as the property name for the strings. eg. ilib.data.strings_CH for Swiss strings, regardless of language, or ilib.data.strings_uz_Cyrl for strings in Uzbek written in Cyrllic. (Uzbek is commonly written in Latin, Cyrllic, or Arabic script, so you have to specify which one you want.)

    Dynamically loaded

    If you have created an ilib.Loader class which is an expert in retrieving your files where they are stored, you can use that loader to load in your string files as well as ilib's locale data files.

    The ilib source code includes a loader for nodejs, so you can see a real working example of how to make one. We're planning to write an XHR loader for web pages some time so that locale data can be loaded as needed. This would necessitate using ilib in an async fashion though. (Let us know if you need this XHR loader sooner rather than later.)

    If you have a loader, you can create a directory structure with the translated files in it. The directory would be located in the same place as your index.html so that all files are relative to it.

    Here is an example structure that contains translations for a few locales:

    index.html
    resources/
      strings.json
      de/
        strings.json
        CH/
          strings.json
      fr/
        strings.json
        CA/
          strings.json
    

    The top-level json file is the default English, which gets overridden by strings from the other json files for other locales.

    'Why would you want an English to English translation?' you might ask. The answer is that this is an extra level of indirection. For example, this "translation" could be used if your marketing or UX department suddenly decides to change the text of a string, but you don't want to change your code and retest everything. Let's say they decide they want to get rid of the "back" part and want our string to say simply, "Welcome, {username}." You can do that in the English strings.json at the top level:

    {
        "Welcome back, {username}.": "Welcome, {username}."
    }
    

    Voila, the UI has changed, but your code has not!

    Of course, if you do that, you should remember to retranslate that same string in all the other strings.json files.

    Let's say your current locale is "de-CH" (German for Switzerland). The resource bundle will load the files in this order:

    1. resources/strings.json
    2. resources/de/strings.json
    3. resources/de/CH/strings.json

    The more locale-specific strings will override the more generic strings at the top level.

    Hope this makes things more clear. Let me know if you have further questions!

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.