Hi5 Developer Center

Internationalization

  1. Languages and Locales
  2. How to i18n an App
    1. Create Message Bundle
    2. Make the Message Bundle available to the App
    3. i18n App attributes
    4. Adding Additional language support
    5. i18n the App
    6. Parameterization using Javascript
    7. Templates
  3. i18n Tips
  4. hi5's Translation Service
  5. Supported Languages and Countries

Languages and Locales

hi5 is available in over 20 languages, with more being added each month.

hi5 maps each of its supported languages to a specific Locale. A Locale is a language/country pair in the format xx_YY, where:

  • xx is a lower-case two letter language code as defined by ISO-639-1 and
  • YY is the ISO country code upper-case, two-letter codes as defined by ISO-3166-1.

hi5 members select a language upon registration and may change it at any time. Note, that the Locale country may be different than the member's Profile country. For a list of locales supported by hi5, see Supported Languages and Countries.


How to i18n an App

In general, most developers begin by writing gadgets with their strings "hard-coded." Supporting multiple languages requires externalizing the user-visible strings into message bundles, a process called internationalization (i18n). This is a quick tutorial on how to i18n your App on hi5. If you're looking for a more detailed explanation on internationalization, please check out http://code.google.com/apis/gadgets/docs/i18n.html

1. Create Message Bundle

A message bundle is an xml file that contains the strings (text) for an App. Each string is identified by a unique name (key) that is the same across bundles. Here's a very simple example of one:

<messagebundle>
  <msg name="title">Gifts Tutorial</msg>
<messagebundle>

In this example - 'title' is the key and 'Gifts Tutorial' is the text to be rendered.

By convention, message bundles should be saved with xx_YY.xml format where xx is the 2-letter iso-639-1 language code and YY is the 2-letter iso-3166-1 country code. There is also a wildcard variable, 'ALL', that can be used for either the language or the country.

Every i18n App should have a default message bundle named ALL_ALL.xml. This default bundle will be used if an appropriate bundle for the user can not be found. See more about message fallback at http://code.google.com/apis/gadgets/docs/i18n.html#Fallback

Message bundles can be hosted on any publicly available server. For example our gift App resource bundle is hosted at http://images.hi5.com/images/opensocial/ALL_ALL.xml

2. Make the Message Bundle available to the App

In the Moduleprefs section, define a Locale element specifying the location of the message bundle. For example:

<ModulePrefs>
  <Locale messages="http://images.hi5.com/images/opensocial/ALL_ALL.xml"/>
</ModulePrefs>

3. i18n App attributes

There are several App attributes that can i18n. If there is a message bundle defined for your App, the App attributes are treated as keys into the message bundle. Note, if the key is not found in the message bundle, the key will be used as the value.

Here's an example of how to i18n the title and image.

Before i18n:

<ModulePrefs title="Gifts Tutorial" 
thumbnail="http://images.hi5.com/images/opensocial/gifts_120x60.gif">
</ModulePrefs>

After i18n:

<ModulePrefs title="appTitle" thumbnail="appImageUrl">
  <Locale messages="http://images.hi5.com/images/opensocial/ALL_ALL.xml"/>
</ModulePrefs>

And the associated message bundle, ALL_ALL.xml will look like this:

<messagebundle>
  <msg name="appTitle">Gifts Tutorial</msg>
  <msg name="appImageUrl">                
     http://images.hi5.com/images/opensocial/gifts_120x60.gif
  </msg>
<messagebundle>

The possible Moduleprefs attributes you can i18n are:

  • title: The name of the App
  • summary: The summary of the App. Typically < 100 characters.
  • description: A more detailed description of the App. Typically < 500 characters.
  • imageUrl: The location of the image associated with the App. Use 120x160 jpg, png or gif

Note, you may find it useful to use your App attributes as the actual keys in your bundle. If for what ever reason your resource bundle is unavailable or if your App is on another container that does not have i18n support, it will at least have a reasonable title. So for example you could left the Module Prefs as it was:

<ModulePrefs title="Gifts Tutorial" thumbnail="http://images.hi5.com/images/opensocial/gifts_120x60.gif">
  <Locale messages="http://images.hi5.com/images/opensocial/ALL_ALL.xml"/>
</ModulePrefs>

And then just use the following keys in the message bundle instead:

<messagebundle>
  <msg name="Gifts Tutorial">Gifts Tutorial</msg>
  <msg name="http://images.hi5.com/images/opensocial/gifts_120x60.gif">
    http://images.hi5.com/images/opensocial/gifts_120x60.gif
  </msg>
<messagebundle>

4. Adding Additional language support

For each additional language you would like your App to support, you need to do 2 things:

  1. Create and publish another message bundle with the translated text
  2. Add another Locale element to your Moduleprefs

Here's an example of adding Spanish:

<ModulePrefs title="appTitle" thumbnail="appImageUrl">
  <Locale messages="http://images.hi5.com/gifts/ALL_ALL.xml"/>
  <Locale messages="http://images.hi5.com/gifts/es_ALL.xml" lang="es"/>
</ModulePrefs>

Note the lang attribute on the 2nd locale.

And the associated message bundle, es_ALL.xml will look like this:

<messagebundle>
  <msg name="appTitle">Guía sobre Regalos</msg>
  <msg name="appImageUrl">http://images.hi5.com/images/opensocial/gifts_120x60_es.gif</msg>
<messagebundle>

Note that the Spanish message bundle (http://images.hi5.com/gifts/es_ALL.xml) is identical to the default (English) message bundle with the exception of the values.

5. i18n the App

The gadgets.Prefs class provides among other things, access to the resource bundles. Prefs has a method, getMsg, that should be used for retrieving messages from a bundle given a key. Here's a simple example:

Before i18n:

  <Content type="html">
    <![CDATA[
      <div id='main' class='main' style="width: 100%; font-size: 12px">
        <h1>Gifts Tutorial by hi5</h1>
      </div>
      ]]>
   </Content>

After i18n:

  <Content type="html">
    <![CDATA[
      <div id='main' class='main' style="width: 100%; font-size: 12px">
        <script type="text/javascript">
          var prefs = new gadgets.Prefs();
          document.write("<h1>" + prefs.getMsg("tutorial") + "</h1>");
        </script>
      </div>
      ]]>
   </Content>

and the message bundle entry would be:

<messagebundle>
  <msg name="tutorial">Gifts Tutorial by hi5</msg>
<messagebundle>

6. Parameterization using Javascript

Sometimes it is necessary to provide parameters to i18n text. For example, "Jack gave Jill a gift" should be parameterized by making Jack, Jill and gift parameters.

So the entry in the message bundle would be:

<messagebundle>
  <msg name="gaveGift">{0} gave {1} a {2}</msg>
<messagebundle>

Note parameters are just an identifiers and do not have to be numbers. So a more verbose, but more descriptive way to parametrize the sentence would be:

<messagebundle>
  <msg name="gaveGift">{fromPerson} gave {toPerson} a {gift}</msg>
<messagebundle>

You can use simple Javascript substitution to replace the parameters with the real values. Here's an example:

Before i18n:

  <Content type="html">
    <![CDATA[
        <div id="giftList"></div>
        <script type="text/javascript">
          var html = new Array();
          html.push('<ul>');
          var owner = 'Jack';
          var friend = 'Jill';
          var gifts = ['gift1', 'gift2', 'gift3', 'gift4'];
          for (i in gifts) {
            html.push(owner + ' gave ' + friend + ' a ' + options[gifts[i]]);
          }
          html.push('</ul>');
          document.getElementById('giftList').innerHTML = html.join('');
        </script>
      ]]>
   </Content>

After i18n:

  <Content type="html">
        <div id="giftList"></div>
        <script type="text/javascript">
          var html = new Array();
          html.push('<ul>');
          var owner = 'Jack';
          var friend = 'Jill';
          var gifts = ['gift1', 'gift2', 'gift3', 'gift4'];
          for (i in gifts) {
            var message = fmtMsg('gaveGift', {fromPerson: owner, toPerson: friend, gift: options[gifts[i]]});
            html.push(message);
          }
          html.push('</ul>');
          document.getElementById('giftList').innerHTML = html.join('');

        <!-- Convenience js method for formatting messages -->
        fmtMsg = function(key, substitutions) {         
                var message = prefs.getMsg(key);        
                for (subst in substitutions) {
                        message = message.replace('${' + subst + '}', substitutions[subst]);
                }
                return message;
        }
        </script>
      ]]>
   </Content>

7. Templates

This is a quick example on how to use hi5 templates. If you're looking for a more detailed explanation on hi5 templates, please check out http://www.hi5networks.com/platform/wiki/CustomTags

Here's a simple example Before i18n:

  <Content type="html">
    <![CDATA[
      <!-- Title Div -->
      <div id='main' class='main' style="width: 100%; font-size: 12px">
        <h1>Gifts Tutorial by hi5</h1>
      </div>
      ]]>
   </Content>

After i18n:

  <Content type="html">
    <![CDATA[
      <!-- Title Div - with no content -->
      <div id='main' class='main' style="width: 100%; font-size: 12px"></div>
      <!-- Template -->
      <script type="text/xml" id="tutorialTemplate">
        <hi5:template xmlns:hi5="http://www.w3.org/1999/xhtml">
          <h1><hi5:message key="tutorial"/></h1>
        </hi5:template>
      </script>       
      <!-- Applying the Template -->
      <script type="text/javascript">
        hi5.template.apply('tutorialTemplate','main');
      </script>
      ]]>
   </Content>

And here's an example of the Templated version of parameterization.

Before i18n:

  <Content type="html">
    <![CDATA[
        <div id="giftList"></div>
        <script type="text/javascript">
          var html = new Array();
          html.push('<ul>');
          var owner = 'Jack';
          var friend = 'Jill';
          var gifts = ['gift1', 'gift2', 'gift3', 'gift4'];
          for (i in gifts) {
            html.push(owner + ' gave ' + friend + ' a ' + options[gifts[i]]);
          }
          html.push('</ul>');
          document.getElementById('giftList').innerHTML = html.join('');
        </script>
      ]]>
   </Content>

After i18n:

  <Content type="html">
    <![CDATA[
        <div id="giftList"></div>
        <script type="text/xml" id="paramTemplate">
            <hi5:template xmlns:hi5="http://www.w3.org/1999/xhtml">
              <ul>
                <for-each var="gift" source="gifts">
                  <li><hi5:message key="gaveGift" fromPerson="${fromPerson}" toPerson="${toUser}" gift="${gift}"/></li>
                </for-each>
              </ul>
            </hi5:template>
        </script>
      <!-- Applying the Template -->
      <script type="text/javascript">
        var owner = 'Jack';
        var friend = 'Jill';
        var gifts = ['gift1', 'gift2', 'gift3', 'gift4'];
        hi5.template.apply('paramTemplate','giftList', {fromPerson: owner, toPerson: friend, gifts: gifts);
      </script>
      ]]>
   </Content>

i18n Tips

These tips are meant to help you get the best possible translation for your text.

  • Don't use concatenation or layout to combine properties into sentences
  • As a general rule, try to externalize complete sentences or phrases
  • Don't Impose Grammar (English or otherwise)
  • Include punctuation in your messages
  • Parameterize nouns and counts; not verbs, pronouns, particles, or other components of the sentence
  • Context can simplify the message, and make the site sound more natural.
  • Keep it simple

hi5's Translation Service

hi5 will announce its translation service for OpenSocial gadgets soon. Details are forthcoming, but the solution will be tightly integrated into the hi5 Developer's Console. Translations will be supplied from a mixture of professional and crowd-sourced translators, and cover all of hi5's growing list of production languages.

Stay tuned for further details.


Supported Languages and Countries

* indicates 'ALL' or not specified

Native Language NameLanguageCountryhi5 LocaleSuggested Bundle Name
Español (España)esESes_ESes_ES.xml
Español (Argentina)esARes_ARes_AR.xml
Españoles*es_MXes_ALL.xml
Português (Brasil)ptBRpt_BRpt_BR.xml
Português (Portugal)ptPTpt_PTpt_PT.xml
Françaisfr*frfr_ALL.xml
Deutschde*dede_ALL.xml
Italianoit*itit_ALL.xml
Nederlandsnl*nlnl_ALL.xml
ภาษาไทยthTHth_THth_TH.xml
日本語ja*jaja_ALL.xml
Polskipl*plpl_ALL.xml
Românăro*roro_ALL.xml
Русскийru*ruru_ALL.xml
Türkçetr*trtr_ALL.xml
中文 (简体)zhCNzh_CNzh_CN.xml
中文(繁體)zhTWzh_TWzh_TW.xml
ČeskycsCZcs_CZcs_CZ.xml
MagyarhuHUhu_HUhu_HU.xml
УкраїнськаukUAuk_UAuk_UA.xml
한국어koKRko_KRko_KR.xml
ΕλληνικάelGRel_GRel_GR.xml
Englishen*enen_ALL.xml
English (default)**enALL_ALL.xml
© 2008 hi5Networks