![Page 1: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/1.jpg)
Translated Strings and Foreign Language
Support in JavaScript Web Apps
Ken TaborTwitter: @KenTabor
![Page 2: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/2.jpg)
Shared
bit.ly/KenOscon13
![Page 3: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/3.jpg)
Translating What?
Any and all blocks of text
![Page 4: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/4.jpg)
Translating What?
Date/time formatters
![Page 5: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/5.jpg)
Translating Where?
Single page app
![Page 6: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/6.jpg)
Translating Myth #1
We don’t need translated text, we’re only shipping to North America
![Page 7: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/7.jpg)
Translating Myth #2
No need - it’s just an internal tool
![Page 8: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/8.jpg)
Translating Myth #3
We’re a start-up ... let’s just submit
![Page 9: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/9.jpg)
Translating OMG #1
Just before code freeze marketing asks:
![Page 10: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/10.jpg)
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.
![Page 11: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/11.jpg)
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.
![Page 12: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/12.jpg)
Translating OMG #2
CoderSean and PM build create() feature
“Connection error, notifying the admin.”
![Page 13: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/13.jpg)
Translating OMG #2
CoderBurin and BA build add() feature
“Network problem. Notifying the admin.”
![Page 14: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/14.jpg)
Why Work Smarter?
Programmers: Don’t Repeat Yourself
Business: Include More Customers
Marketing: Craft Consistent Message
![Page 15: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/15.jpg)
Solution?
String Tables
![Page 16: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/16.jpg)
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'};
![Page 17: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/17.jpg)
Architectural Rule #1
Never hard-code text strings
![Page 18: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/18.jpg)
Architectural Rule #2
String-tables must be easily accessed throughout the application
![Page 19: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/19.jpg)
Architectural Rule #3
Language string-tables must be demand-loadable resources
![Page 20: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/20.jpg)
Is this Difficult?
Couldn’t Google my way out of this task
JavaScript is popular lacks formal support
We’re all rushed after all
![Page 21: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/21.jpg)
![Page 22: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/22.jpg)
Who Am I to Do This?
I’m a front-end product engineer
Working at Sabre Holdings
Building TripCase
![Page 23: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/23.jpg)
![Page 24: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/24.jpg)
Our Dev Strategy
Mobile web browser (webkit)
![Page 25: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/25.jpg)
Our Dev Strategy
iOS and Android native apps (PhoneGap)
![Page 26: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/26.jpg)
Our Dev Strategy
Coders get smart and stay smart
![Page 27: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/27.jpg)
Core Languages
App Structure
Presentation Layer
Utility Libs
Code Analysis/Build
Native Wrapper
![Page 28: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/28.jpg)
JavaScript + CSS + HTML
Backbone + Underscore + RequireJS
jQuery + SASS + Compass
Handlebars + Moment + Modernizr
Jasmine + jsHint + Plato + Grunt
PhoneGap
![Page 29: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/29.jpg)
Demo
Show the people some running code
![Page 30: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/30.jpg)
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'};
![Page 31: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/31.jpg)
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;
![Page 32: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/32.jpg)
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'
![Page 33: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/33.jpg)
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 %>'
![Page 34: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/34.jpg)
JavaScript User
function onSelectChoice(id) { var userModel;
userModel = this.collection.get(id); alert(TS.tstring.selectedProgram + ': ' + userModel.getDisplayTitle());}
![Page 35: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/35.jpg)
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(); } });}
![Page 36: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/36.jpg)
Making the Case
Combine duplicating strings
Stop nearly duplicated strings
Easier word-smithing
Setup for translation services
Abstract away date/time formatting
![Page 37: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/37.jpg)
Handlebars User
Write a “helper” function
Wraps the global resource
Param indexes into the string table
![Page 38: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/38.jpg)
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>
![Page 39: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/39.jpg)
RequireJS
RequireJS has “i18n” plugin
Auto-loads based on navigator.language
At the cost of user control
![Page 40: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/40.jpg)
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;
![Page 41: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/41.jpg)
Testing
Test entire app in English
Native speaker confirms translations
Wait on bug reports
![Page 42: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/42.jpg)
Testing
Automated testing: Jasmine and Selenium
Manual debug: English with “SP-” prefix
![Page 43: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/43.jpg)
The “Ken Bug”
Don’t accidentally ship your debug files
![Page 44: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/44.jpg)
Think About It
Start from the start
Retrofitting costed a 50hr week
Plus 20hr regression testing
![Page 45: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/45.jpg)
Think About It
Server-side error conditions happen
Map return codes rather than text
![Page 46: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/46.jpg)
Keep Thinking
Pluralization functions
![Page 47: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/47.jpg)
Keep Thinking
Coordinate with plugins & libraries
![Page 48: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/48.jpg)
Keep Thinking
Designers must brain-sweat composition
![Page 49: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/49.jpg)
Questions?
![Page 50: Translated Strings and Foreign Language Support in JavaScript Web Apps - OSCON 2013](https://reader036.vdocuments.mx/reader036/viewer/2022081800/554a0fdbb4c905825d8b49a4/html5/thumbnails/50.jpg)
Thank-You
bit.ly/KenOscon13Ken Tabor (@KenTabor)