Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013

  • 1,063 views
Uploaded on

Most apps of a significant viral popularity, or even modest ones providing value in the enterprise, need to implement foreign languages. Why? Supporting the largest possible audience in today’s......

Most apps of a significant viral popularity, or even modest ones providing value in the enterprise, need to implement foreign languages. Why? Supporting the largest possible audience in today’s connected world lets programmers create an opportunity for expanding the business. Find supporting demo app and GitHub repo here: bit.ly/KenOscon13

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,063
On Slideshare
1,050
From Embeds
13
Number of Embeds
2

Actions

Shares
Downloads
8
Comments
0
Likes
1

Embeds 13

http://lanyrd.com 10
https://twitter.com 3

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Translated Strings and Foreign Language Support in JavaScript Web Apps Ken Tabor Twitter: @KenTabor
  • 2. Shared bit.ly/KenOscon13
  • 3. Translating What? Any and all blocks of text
  • 4. Translating What? Date/time formatters
  • 5. Translating Where? Single page app
  • 6. Translating Myth #1 We don’t need translated text, we’re only shipping to North America
  • 7. Translating Myth #2 No need - it’s just an internal tool
  • 8. Translating Myth #3 We’re a start-up ... let’s just submit
  • 9. Translating OMG #1 Just before code freeze marketing asks:
  • 10. Translating OMG #1 Just before code freeze marketing asks: Hey, will you send over all the text please? We want to do a polish pass for voice and message before ship.
  • 11. Translating OMG #1 Just before code freeze marketing asks: Hey, will you send over all the text please? We want to do a polish pass for voice and message before ship. Don’t worry we’ll return it by end of day.
  • 12. Translating OMG #2 CoderSean and PM build create() feature “Connection error, notifying the admin.”
  • 13. Translating OMG #2 CoderBurin and BA build add() feature “Network problem. Notifying the admin.”
  • 14. Why Work Smarter? Programmers: Don’t RepeatYourself Business: Include More Customers Marketing: Craft Consistent Message
  • 15. Solution? String Tables
  • 16. Typical String Table TS.tstring = { appTitle: 'TString.JS', programListing: 'Program Listing', english: 'English', spanish: 'Spanish', german: 'German', title: 'Title', date: 'Date', synopsis: 'Synopsis', programDate: 'MMM Do YYYY, h:mm a' };
  • 17. Architectural Rule #1 Never hard-code text strings
  • 18. Architectural Rule #2 String-tables must be easily accessed throughout the application
  • 19. Architectural Rule #3 Language string-tables must be demand- loadable resources
  • 20. Is this Difficult? Couldn’t Google my way out of this task JavaScript is popular lacks formal support We’re all rushed after all
  • 21. Who Am I to Do This? I’m a front-end product engineer Working at Sabre Holdings Building TripCase
  • 22. Our Dev Strategy Mobile web browser (webkit)
  • 23. Our Dev Strategy iOS and Android native apps (PhoneGap)
  • 24. Our Dev Strategy Coders get smart and stay smart
  • 25. Core Languages App Structure Presentation Layer Utility Libs Code Analysis/Build Native Wrapper
  • 26. JavaScript + CSS + HTML Backbone + Underscore + RequireJS jQuery + SASS + Compass Handlebars + Moment + Modernizr Jasmine + jsHint + Plato + Grunt PhoneGap
  • 27. Demo Show the people some running code
  • 28. String Table TS.tstring = { appTitle: 'TString.JS', programListing: 'Program Listing', english: 'English', spanish: 'Spanish', german: 'German', title: 'Title', date: 'Date', synopsis: 'Synopsis', programDate: 'MMM Do YYYY, h:mm a' };
  • 29. Global Resource // encapsulate all code modules into a global namespace var TS = TS || {}; TS.model = TS.model || {}; TS.view = TS.view || {}; TS.collection = TS.collection || {}; TS.app = null; TS.tstring = null;
  • 30. Template User TS.view.Application = Backbone.View.extend({ template: '<h1>TStringJS</h1>' + '<h2>Example of translated strings and foreign language</h2>' + '<select id="lang-list">' + '<option value="english">English</option>' + '<option value="spanish">Spanish</option>' + '<option value="french">French</option>' + '<option value="italian">Italian</option>' + '</select>' + '<button id="lang-load">Select'
  • 31. Template User TS.view.Application = Backbone.View.extend({ template: '<h1><%= TS.tstring.appTitle %></h1>' + '<h2><%= TS.tstring.appSubTitle %></h2>' + '<select id="lang-list">' + '<option value="english"><%= TS.tstring.english %></option>' + '<option value="spanish"><%= TS.tstring.spanish %></option>' + '<option value="french"><%= TS.tstring.french %></option>' + '<option value="italian"><%= TS.tstring.italian %></option>' + '</select>' + '<button id="lang-load"><%= TS.tstring.select %>'
  • 32. JavaScript User function onSelectChoice(id) { var userModel; userModel = this.collection.get(id); alert(TS.tstring.selectedProgram + ': ' + userModel.getDisplayTitle()); }
  • 33. Resource Loader function LanguageLoad(lang) { var langFn; if (lang === 'english') langFn = 'en-US.js'; else if (lang === 'spanish') langFn = 'es.js'; else if (lang === 'klingon') langFn = 'tlh.js'; $.ajax({ url: 'code/strings/' + langFn, dataType: 'script', success: function(data, textStatus) { TS.app.onRender(); } }); }
  • 34. Making the Case Combine duplicating strings Stop nearly duplicated strings Easier word-smithing Setup for translation services Abstract away date/time formatting
  • 35. Handlebars User Write a “helper” function Wraps the global resource Param indexes into the string table
  • 36. Handlebars Helper Handlebars.registerHelper('tstring', function(key) { var tstring = TS.tstring[key]; if (tstring === undefined) console.log('Missing string[' + key + ']'); return tstring; }); <h1>{{tstring “appTitle”}}</h1> <h2>{{tstring “appSubTitle”}}</h2>
  • 37. RequireJS RequireJS has “i18n” plugin Auto-loads based on navigator.language At the cost of user control
  • 38. Native App All string files are packaged together TS.tstring.en = {...}; TS.tstring.fr = {...}; TS.tstring.es = {...}; TS.tstring.tlh = {...}; TS.tstrings = TS.tstring.es;
  • 39. Testing Test entire app in English Native speaker confirms translations Wait on bug reports
  • 40. Testing Automated testing: Jasmine and Selenium Manual debug: English with “SP-” prefix
  • 41. The “Ken Bug” Don’t accidentally ship your debug files
  • 42. Think About It Start from the start Retrofitting costed a 50hr week Plus 20hr regression testing
  • 43. Think About It Server-side error conditions happen Map return codes rather than text
  • 44. Keep Thinking Pluralization functions
  • 45. Keep Thinking Coordinate with plugins & libraries
  • 46. Keep Thinking Designers must brain-sweat composition
  • 47. Questions?
  • 48. Thank-You bit.ly/KenOscon13 Ken Tabor (@KenTabor)