Let’s start by defining a measure of success. The application as I start is fully functional and written for English users. I’m not the developer of the application but I have obtained the source code from a GitHub repository, meaning it is open source, and I do not have any personal relation to the original author. To consider my task successful I will need to accomplish a few things.
- The original author shall approve my code changes and merge my version of the application with the official version on GitHub. In GitHub this is normally done with a pull request.
- The default language shall still be English but a compiled version shall allow the users to swap to “any” other language (for which a translation exist) and use it with the the same functions as before.
- I can obviously only translate to languages that I speak and therefore I will need to find help for other languages. For this I will use crowd sourcing and a service called Transifex. The idea here is very simple, I will upload a file with English words and anyone can suggest and translate to a language of their choosing. Once the translation is complete I can download the newly translated words and add to the application.
- Since the previous point is dependent on people I don’t know, I will still consider the project a success if no one volunteers to translate. As a proof of concept I will translate on Transifex to one other language, and thus make the application bi-lingual. The application code shall however be extended in such a way that another language can be added once a translation is available and there shall be documentation for how to do so.
- The name of the application and where to find the source code, the Transifex repository and application executable shall be announced here and on other channels.
Next I define a strategy and break down what and what changes are required to the application code to accomplish this. The application is a .Net 4.5 application and it’s written in Visual Basic. Although Visual Basic is not my strongest programming language I feel confident that I can solve this problem with my previous experience in .Net. I intend to use as much as possible of the framework to support this so a few things mentioned here may be specific to .Net but the general concept I believe are applicable to any other software application.
- The first change I need to make is to map and externalize all English strings of the application. The framework has concepts of Resource files, Satellite Assemblies, CultureInfo, and Resource Management so I will rely on the framework and not reinvent things already existing.
- Words in different languages have different number of characters which may cause string expansion or contraction. This means that an element of the application interface may grow or shrink in size as the locale is changed. The most straight forward solution is to increase the placeholder, the control, to fit the longest string.
- Text in images can’t be translated so any text inside an image needs to be refactored to a string variable if it shall be translated.
- String concatenation of strings presented in the UI is a bad idea and should be avoided. Some languages use a reversed word order.
- All numbers shall be localized because both the comma “,” and the dot “.” can be used as the decimal separator instead of the “.”. Furthermore, some locales allow a comma be used to separate thousands.
- Sorting collections shall be dependent on the locale as the sorting order may be different. Any sort shall rely on the sort function of the framework for the specific locale.
- If the application has phone numbers, postal codes or any locale specific entity they should be formatted and presented according to accepted conventions.
- Fixed or hardcoded paths to Windows folders must be avoided. For example the path “C:/Program Files” may not be called the same on OS with a different language.
The above bullet points are not everything that may be considered, and some may not even apply for certain types of applications. It’s important to understand this and be dynamic when approaching the upcoming work. I started on this list before I examined the code and will remove or add things if I discover other aspects of the localization at a later stage. It’s important to test and iterate this. One could even formulate test cases with the bullets and the application use cases in mind. Due to the size of the project I chose not to do this formally.
I expect the number of languages and cultures to grow over time as more translations are completed on Transifex. For a new language to be supported by the application a resource file need to be added to GitHub and a satellite assembly included with the application release. I'm still investigating the most straightforward way, other than manually repeating the steps, to accomplish this.