not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
7.1 KiB

  1. [Go back to tutorial home](tutorial.md)
  2. # Step 5: localize the activity
  3. *(Estimated time: 15mn)*
  4. Your current Sugarizer session talks probably the same language as you. At the first setup, Sugarizer detects the language of your browser and uses this language for the UI and the activities
  5. You could also change the language from the settings. Hover the mouse on the XO buddy icon on the Sugarizer home view and then click on settings, then to "Language" to display the language settings window.
  6. ![](images/tutorial_step5_1.png)
  7. If you choose another language, this new language will be use for all activities. Let's see how we could use it in our Pawn activity too.
  8. ### Identify strings to localize
  9. Sugarizer and Sugar-Web use the [webL10n](https://github.com/fabi1cazenave/webL10n) JavaScript library to handle localization.
  10. The first step when you localize an activity is to identify strings to localize. It means replace hard-coded string in your HTML or JavaScript files by localization resources. In the Pawn activity we've got three strings to localize:
  11. * *"Hello {user}"*: the welcome message
  12. * *"{user} played!"*: when the user played a pawn
  13. * *"Add pawn"*: the helper message on the toolbar button
  14. With the webL10n library all strings have to be define in a specific file where all translations for each strings should be set. We call this file `locale.ini`. So using your text editor, let's create a `locale.ini` file at the root of the Pawn activity. Here what it look likes:
  15. [*]
  16. Hello=Hello {{name}}!
  17. Played={{name}} played
  18. AddPawn=Add pawn
  19. [en]
  20. Hello=Hello {{name}}!
  21. Played={{name}} played
  22. AddPawn=Add pawn
  23. [fr]
  24. Hello=Bonjour {{name}} !
  25. Played={{name}} a joué
  26. AddPawn=Ajouter pion
  27. [es]
  28. Hello=Hola {{name}} !
  29. Played={{name}} jugó
  30. AddPawn=Agrega un peón
  31. This file is decomposed into sections. One section for each language with the language code between brackets as section name (**en**, **fr**, **es**, ...) and a special section (**\***) for unknown language.
  32. In each section you have to define translations for each strings. The left side of the equal sign is the id of the string (**Hello**, **Played**, **AddPawn**), the right side of the equal sign is the translated string.
  33. For parameterized strings (i.e. strings where a value is inside the string), the double curved bracket **\{\{\}\}** notation is used.
  34. Now we will integrate our new `locale.ini` file into `index.html`:
  35. <!DOCTYPE html>
  36. <html>
  37. <head>
  38. <meta charset="utf-8" />
  39. <title>Pawn Activity</title>
  40. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, viewport-fit=cover"/>
  41. <!-- Add locale.ini file -->
  42. <link rel="prefetch" type="application/l10n" href="locale.ini">
  43. <link rel="stylesheet" media="not screen and (device-width: 1200px) and (device-height: 900px)"
  44. href="lib/sugar-web/graphics/css/sugar-96dpi.css">
  45. ...
  46. </html>
  47. The file is include as a HTML `link` tag and must have a `application/l10n` type to be recognize by webL10n library.
  48. ### Initialize localization
  49. We will now see how to initialize localization into the activity source code.
  50. Once again we will have first to integrate a new dependance. So let's add the webL10n library in the first line of `activity/activity.js`:
  51. define(["sugar-web/activity/activity", "sugar-web/env", "sugar-web/graphics/icon", "webL10n"], function (activity, env, icon, webL10n) {
  52. The webL10n library is able to automatically detect the browser language. But in Sugarizer it's different because the language is decided by the user. So our activity have to initialize current language using the user choice. Once again we're going to use the environment feature to determine the user language. Our current `getEnvironment` call in `activity/activity.js` file is like this:
  53. env.getEnvironment(function(err, environment) {
  54. currentenv = environment;
  55. // Load from datatore
  56. if (!environment.objectId) {
  57. console.log("New instance");
  58. } else {
  59. activity.getDatastoreObject().loadAsText(function(error, metadata, data) {
  60. if (error==null && data!=null) {
  61. pawns= JSON.parse(data);
  62. drawPawns();
  63. }
  64. });
  65. }
  66. });
  67. Let's update it like this to set the language:
  68. env.getEnvironment(function(err, environment) {
  69. currentenv = environment;
  70. // Set current language to Sugarizer
  71. var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language;
  72. var language = environment.user ? environment.user.language : defaultLanguage;
  73. webL10n.language.code = language;
  74. // Load from datatore
  75. if (!environment.objectId) {
  76. console.log("New instance");
  77. } else {
  78. activity.getDatastoreObject().loadAsText(function(error, metadata, data) {
  79. if (error==null && data!=null) {
  80. pawns = JSON.parse(data);
  81. drawPawns();
  82. }
  83. });
  84. }
  85. });
  86. We're doing three things:
  87. * Determine the `defaultLanguage` for the browser: it's in the `navigator.language` variable except for Chrome OS where you have to get it using a `chrome.i18n.getUILanguage()` call
  88. * Get the user language: it's in `environment.user.language` except if it's not set. In that case we're using the `defaultLanguage`
  89. * Force the language for webL10n library: you just have to set the value for `webL10n.language.code`.
  90. That's all. The right language is now set into webL10n at startup.
  91. ### Set strings value depending of the language
  92. To get the localized version of a string, the webL10n framework provide a simple `get` method. You pass to the method the id of the string (the left side of the plus sign in the INI file) and, if need, the string parameter. So for the welcome message, here is the line to write:
  93. document.getElementById("user").innerHTML = "<h1>"+webL10n.get("Hello", {name:currentenv.user.name})+"</h1>";
  94. As you could see the first `get` parameter is the id of the string (**Hello**) and the second parameter is a JavaScript object where each property is the name of the parameter (the one provided inside double curved brackets **\{\{\}\}**, **name** here). The result of the function is the string localized in the current language set in webL10n.
  95. In a same way, the pawn played message could be rewrite as:
  96. document.getElementById("user").innerHTML = "<h1>"+webL10n.get("Played", {name:currentenv.user.name})+"</h1>";
  97. One point however: we need to wait to initialize strings that the `locale.ini` is read. It's possible because the webL10n framework raise a new `localized` event on the window when the language is ready.
  98. So we will now initialize the welcome message in the `localized` event listener like that, in the end of the require function of `activity/activity.js` file:
  99. // Process localize event
  100. window.addEventListener("localized", function() {
  101. document.getElementById("user").innerHTML = "<h1>"+webL10n.get("Hello", {name:currentenv.user.name})+"</h1>";
  102. document.getElementById("add-button").title = webL10n.get("AddPawn");
  103. });
  104. Everything is now ready to handle localization.
  105. Let's test it. Change the Sugarizer language to French and let's see the result.
  106. ![](images/tutorial_step5_2.png)
  107. The welcome message and the button placeholder is now in French. The played message works too.
  108. [Go to next step](tutorial_step6.md)