When I start developing and throwing out code, I can tell you I’m too concentrated in the features and how I want things to work out. Always testing and debugging and running around different possibilities in my head on how that piece of code could go wrong.
When writing elements on the interface, I just tend to place the needed controls or the html tags on web pages and add the labels to the respective controls. The labels just pop out of my head without even noticing what I’m writing. Most of the time I’m just thinking how the feature is going to work with the control.
So, when your application is finished, features are implemented, and then we begin with the cosmetic work. This is when the problem arises. If you intent is to offer your application in multiple languages, then localizing the controls and html pages is not part of the cosmetic work. The only way to localize your app when all the labels are hard coded is to make a copy of the web page or control, with the same code, and start changing the labels manually.
That’s why I always have a localization strategy before beginning throwing out the code. Even if you decide how the language engine is going to work after you’ve hardcoded the labels, the simple task of changing them to the variables is exhausting. After months of going through this process with some applications that didn’t have a localization strategy, I’m stilling finding hard coded labels.
Here are some simple strategies I’ve used:
- Desktop applications (server side): I always try to save the labels on the database repository of the application. Using this technique, I can add languages and modify labels without having to compile the application. Sometimes, developers embedded the label files in the executable itself, the drawback with this technique is having to recompile for adding new languages. With the database option, you just have to create generic functions to get labels out of the repository. I usually have four special fields for identifying the label: the screen or page, the name of the control, the language and the label value. It’s easy to find labels for a specific screen or page this way and save them on memory. Just one query to the database.
- Desktop applications (client side): I don’t like very much this technique, storing language files in the application local folder. For me, it seems prone for failure: what if the user deletes the file, what if the user opens the file and changes the labels, etc. If you need to store files on the hard disk, try to encrypt them and have some default language embedded in the app executable just in case the language files are deleted.
- Web application (server side labels): Again, the labels are stored in the database as in the previous technique, although some complications might arise. Remember getting a label value involves making a query for three fields in the database: the page, the language and the control. You might be able to make a function that gets all labels for a page and dynamically find the controls and assign the labels, but I always find it difficult to loop for controls in the page. On our projects I use the Custom Expression Builder functionality from ASP.NET. I’m able to assign the label in the HTML page and dynamically the .NET Framework detects the page and the label is passed as a parameter and then goes to the backend database to get the information. This way there’s never a hard coded value in the HTML. The only issue is that every label is a different request to the database. For one page with 20 labels and a thousand users seeing the page it comes to 20,000 queries to the DB for labels. What I did in this case is to implement a caching mechanism to store the label values in a file on the server. First I check the cache, and as a second option go to the database. Labels do not change that frequently, so the cache can last for a whole day without any issues. This is the technique used on all our websites (SkyXoft, RequestSpot).
Any of these techniques should be enough for localizing an application. The most important issue here is to plan for language support before coding starts. Doing it afterward is a never ending work. Hidden hard coded labels appear every day.
If you want more information about the code we use or you have any other technique for localization, let me know in the comments.