By Shobana Radhakrishnan and Josh Iverson
Mindflash offers a cloud-hosted learning management solution serving 1000+ medium and large enterprise customers across 35 countries. These customers use our system to train their employees, sales and support workforce, third parties and even their customers.
Our initial focus was for US-based customers, later expanding to customers from across the world, but still speaking and training primarily in English. As our business further expanded we started seeing more and more larger companies with a global and dynamic workforce (see our website for some of our global customers) with thousands of trainees. This meant that our customer base had an increasing need for multi-language support to train global teams with training material developed primarily in English.
Key Use Cases
Analysing our user base, the majority use case was a company with headquarters in an English-speaking country needing to train employees or other trainees in other countries speaking predominantly other languages.
Another use case that is evolving at a rapid pace is shared economy with companies such as AirBnb and TaskRabbit, who need to train a very heterogenous set of people who are, for all practical purposes, part of their workforce, even though they are not employed directly by the respective companies ie. AirBnb or TaskRabbit. This use case has the same language usage pattern where the trainer, an employee of AirBnb or TaskRabbit, could develop the course material in English, but needed the trainee to be able to leverage the training in their local language.
So, in other words, we needed to support multiple languages for our trainee experience, and this was not as critical for our trainer experience..yet.
Also in these cases, the trainer typically has services they can use to translate the course content itself in their companies or otherwise. They just needed the trainee to be able to navigate and completely manage their experience in their local language, including quizzes, surveys and all the reporting and search features in their dashboard that Mindflash provides.
What we Needed To Do
As everyone knows, going global has two important elements for a web application:
The good news is that we already handled the first. We are completely deployed using Amazon’s AWS systems and have cross-region presence, leveraging their CloudFront CDN solution. With this we have highly reliable acceptable (<2s) latency access for all our customers across the world which is constantly monitored.
We just needed to add multi-language support for the trainee experience ie. rendering the course, and the overall trainee experience.
Language support workflow
As we looked for the best options for end-to-end workflow in adding language support, there were two important considerations.
We needed to be able to add languages or make translation changes very quickly so we can be responsive to our customer needs.
Mindflash is a lean startup, so we are usually very conscious of taking on high tech debt or manually-intensive processes, and strive for a high level of tool reuse and open source utilization and contribution.
So a few things were really critical for our workflow:
The Technology Challenge
Our technology stack consists of a mix of things as we are in the middle of our migration out of Flex and .NET code, moving towards Angular.js and Node.js. While most of our application is already in an angular/node-based architecture, there are significant pieces that are in the process of being migrated as well. This means that some of the code that had to be internationalized and localized was in Flex and some of it in Angular and Node.
This code base had been developed over several years so we had some legacy code which was not as well-understood as the rest of the code. This meant that it wasn’t easy to find all the areas to extract language-sensitive strings from.
Since we were looking to use a model of leveraging an external translation firm, in the interest of overall cost and efficiency we wanted to avoid a lot of iterations of finding strings, sending them for translation and testing changes.
In summary, we had a few key challenges as we embarked on this effort:
The translated text was then served under the following conditions:
Here's a screenshot of our Trainee Application before translation:
Our approach for translating various applications across numerous technologies was an interesting undertaking. The first task was implementation in our angular application, since this was going to be the largest piece and most common use case for development. After some initial investigation, and previous localization experience, we decided on the widely used gettext format in conjunction with an, all in one solution, for our angular application called angular-gettext. This means we can use widely established translation tools like Poedit or an online translation platform.
By using angular-gettext we simplified finding, and re-implementing translations, so the process is just 3 easy steps.
1. Mark a string as translatable by simply as adding an attribute:
and it completely understands angular bindings like so:
Hello Going Global with our Online Training System
2. Use the angular-gettext tools to extract those strings to a translation template.
3. Once translated, use the same tools to embed the translations back into your application.
Angular-gettext supplies automated grunt tasks to extract and embed the translations back into your application.
By using what we learned on our angular html application we implemented a very similar process for our express/ejs html.
Express and ejs did not have an all in one solution but there are many node tools for ease of use. We implement grunt-jsxgettext (wrapper for jsxgettext), node-pseudo-l10n and node-gettext-sprintf which were all are on github. But we also needed to open source a few libraries make our express application process model our angular process.
Again the process is very similar for example to implement gettext in an ejs template:
1. Pass the translatable text to a simple dgettext() ejs function:
2. Use the grunt-jsxgettext tools to extract strings to a translation template file.
3. Once translated, use a pseudo locationization library and created the english po file.
Our final process for our angular, express, iOS and flash workflow all follow the same simple procedure:
Here’s how our trainee experience looks with translation. In these examples, the course content has not been translated by the trainer yet, if not the course titles can also appear in the language of choice set by the trainer.
Summary and Next Steps
With this approach, we were able to achieve localization and support for the top 7 requested languages in just two calendar months. This included the ability to perform new text translations or changes in hours, and the ability to add languages in a couple of days.
While this has been adopted by several of our customers effectively for the trainees around the world, we have more work to do along this direction:
If you would like to more about these challenges or about our node implementation, feel free to reach out to us via LinkedIn or Twitter: