Successfully reported this slideshow.

That’s a nice UI, but have you internationalized your Javascript?

904 views

Published on

This session aims to solve the problem of how client-side language strings can easily be hard coded since browsers cannot even report user locale accurately. Not only is there a need to i18n, but a greater need to tap into sakai's i18n powers. UCT work on client-side i18n wrt. Course Evaluations will be showcased. From simple alerts, validation errors and prompts sakai users can see quick responses to their interaction but there is no easy way of ensuring that these messages are internationalized. Using Entity Broker and a tool-level Entity Provider, the Course Evaluations tool currently runs an i18n javascript codebase that implements the powerful i18n standards of Sakai. This session will outline the work at: http://tinyurl.com/yhora2v

Published in: Technology
  • Be the first to comment

  • Be the first to like this

That’s a nice UI, but have you internationalized your Javascript?

  1. 1. That’s a nice UI, but have you internationalized your JavaScript<br />Lovemore Nalube<br />Developer<br />University of Cape Town<br />17 June 2010<br />
  2. 2. Overview<br />Evil ‘n’ Good code<br />Difficulties of i18n-sing JS<br />Why Sakai's needs are unique<br />RESTful access to a Sakai Message bundle<br />DEMO: Course Evaluations and the SMS Credits Transfer tool<br />2<br />11th Sakai Conference - June 15-17, 2010<br />
  3. 3. Sample nasty code<br />Common evil case:<br />Good case:<br />var response = xhr.status;<br />alert("You have an error caused by" + response);<br />var response = xhr.status;<br />alert(messageLocator.getString( “ui.site.error”, response);<br />3<br />11th Sakai Conference - June 15-17, 2010<br />
  4. 4. Difficulties of i18n-sing JS<br />Cannot rely on browser locale<br />Most users are unaware of the presence of this browser setting<br />JS alone cannot get Sakai Preferences locale setting<br />Do we have to re-create message bundles?<br />Inconsistencies, more effort, harder to maintain<br />navigator.language /* Mozilla */|| navigator.userLanguage /* IE */ <br />4<br />11th Sakai Conference - June 15-17, 2010<br />
  5. 5. Why Sakai's needs are different<br />2 stages of language customization:<br />User preference<br />Server configuration<br />Sakai’s own locale lookup is used in many tools<br />Extend this ability to client side tools<br />Date formats vary<br />5<br />11th Sakai Conference - June 15-17, 2010<br />
  6. 6. Fun stuff<br />Steps to follow<br />11th Sakai Conference - June 15-17, 2010<br />6<br />
  7. 7. Step 1: RESTful access to a Sakai Message bundle<br />Tool level Entity Provider<br />creates a fixed URI for getting a message bundle<br />In a webapp, make a provider class:<br />ResourceLoader resourceLoader = <br />new ResourceLoader(MESSAGES_BUNDLE_DIR); <br />// eg. where  MESSAGES_BUNDLE_DIR = <br /> "org.sakaiproject.evaluation.tool.bundle.messages";             <br />*** NEEDS TO BE A FOLDER!<br />return the key-value equivalents of<br />resourceLoader.entrySet().iterator();<br />in (for example) HashMap<br />7<br />11th Sakai Conference - June 15-17, 2010<br />
  8. 8. Step 2: RESTful access to a Sakai Message bundle<br />POM modifications<br />creates a fixed URI for getting a message bundle<br />Depend on Entity Broker:<br />8<br />11th Sakai Conference - June 15-17, 2010<br />
  9. 9. Step 3: RESTful access to a Sakai Message bundle<br />Call Ajax file at JS doc ready:<br />       $.ajax({            url: “/direct/evals-resources/bundle.json”,            global: false,            cache: true,            dataType : "json",            success: function(messageBundleJSON){                messageBundle = messageBundleJSON.data;            }        }); <br />9<br />11th Sakai Conference - June 15-17, 2010<br />
  10. 10. Step 4: RESTful access to a Sakai Message bundle<br />Start using:<br />var removalString = <br />fluid.messageLocator( messageBundle )(["administrate.general.enable.response.removal"]); <br /> <br />*** For values with variable replacers like {0}  <br /> as in removeitem.removed.user.message: "Item ({0}) has been removed",<br />// Decoding the key "removeitem.removed.user.message". <br />//RESULT  removalString = "Item (3) has been removed"<br />var removalString =<br /> fluid.messageLocator( messageBundle )(["removeitem.removed.user.message"], 3 );<br />10<br />11th Sakai Conference - June 15-17, 2010<br />
  11. 11. Step 4.5: RESTful access to a Sakai Message bundle<br />Simpler way to use:<br />Get a language string like this:<br />//retrieve the message strings for key<br /> messageLocator: function(key, params){<br /> return fluid.messageLocator( messageBundle )([key], params); <br /> },<br />var alertError = evalTemplateUtils.messageLocator("evalsettings.email.sent.from", helpEmail.toLowerCase()));<br />//if helpEmail.toLowerCase() = help@sakaiproject.org<br />//prints: All emails will be sent from help@sakaiproject.org<br />11<br />11th Sakai Conference - June 15-17, 2010<br />
  12. 12. Course Evaluations<br />SMS Credits Transfer<br />Demo<br />11th Sakai Conference - June 15-17, 2010<br />12<br />
  13. 13. More info.<br />http://blogs.uct.ac.za/blog/lovemores-world/2009/09/28/consuming-a-sakai-java-messages-resource-bundle-in-javascript-with-fluid-i8n<br />SMS code: https://source.sakaiproject.org/contrib//sms/sms/trunk/user-tool/<br />

×