In this blog we want to talk about localization in software development. We will explore techniques, tools and best practices in software localization that help you avoid the pitfalls of localization and deliver great products to an international audience.
May 2019
In this article we will take a closer look on how to efficiently use the built-in Angular internationalization, commonly know as i18n. The basics of internationalization are covered very well on the official Angular website. If you are starting with Angular internationalization read the official documentation first. In this article we will focus on some practical aspects not mentioned in the official documentation but highly important for an efficient and high quality translation workflow.
This seems rather obvious but Angular let's you place i18n tags at almost every level of your HTML code. The farther away your i18n tag is from the actual translatable text, the more HTML will be inserted into the XLIFF file by the xi18n tool. This will create a huge headache for the translators by making strings much harder to translate. There is also a big risk of translators introducing errors in your HTML resulting in runtime errors of your application.
Let's see some examples:
<div i18n>Title</div>
will be exported to XLIFF as
...<source>Title</source>...
If we now decide to wrap "Title" with a span tag we end up with this
<div i18n><span>Title</span></div>
which will be exported to XLIFF as
...<source><x id="START_TAG_SPAN" ctype="x-span" equiv-text="<span>"/>Title<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="</span>"/></source>...
In practice i18n tags placed on the wrong element happen quite a lot. So watch out for those i18n tags and implement strict and clear guidelines for your team.
When you mark a tag with an i18n tag the xi18n tool generates an automatic ID to uniquely identify the string. This ID is nothing more than a hash of the string itself. Naturally if the string is modified, the ID will change. No matter which translation tool you use (Babylon included), it will recognize the new ID as a new string. This forces translators to translate all target languages of the string when in fact maybe only a typo in the invariant string has been corrected. The old (obsolete) string will likely remain in your translation project forever as it has already been translated (this is not the case with Babylon). So make sure you always set a unique custom ID when you use the i18n tag:
<div i18n="@@MainView_PageTitle">Title</div>
We highly recommend using meaningful ID names. Meaningful to translators. It is sometimes very hard for a translator to get any context of the string she is about to translate. Every little bit of context helps and ID's are a very good way of providing it. It's best if you build your ID's using a standardized scheme, e.g. <ViewName>_<ElementName>. This also help avoiding duplicate ID's.
Yes, we know, adding a meaningful ID to every string is tedious and if you did not start this way in a project it will be very time consuming setting all ID's at a later stage. Don't worry, we are currently working to add an auto-ID feature to Babylon. Stay tuned.
Strings in applications very often contain pieces of information that need to be read from a variable. The text "5 of 10 files have been copied" contains two variables. There are two ways to build this string:
a) Assembly the string by concatenating
files_copied + "of" + total_files + "files have been copied"
b) Use interpolations
"{{files_copied}} of {{total_files}} files have been copied"
Method a makes it very hard for translators. They have no clue the two strings "of" and "files have..." belong together. When using method b on the other hand the xi18n tool writes one string with interpolations to XLIFF. XLIFF editors can interpret interpolations and help translators during translation.
A similar problem arises with plurals like "2 user(s) created" or select expressions like "A red(green) icon indicates...". Both cases can be solved by assembling strings at runtime making it hard for translators. By using plural and select expressions your code will be simpler and life for translators easier.
Feb. 2017
Localization is usually not as complex as it is sometimes presented. All modern development environments support localization and provide the necessary infrastructure to separate strings to be translated from code.
Localization support is integrated directly into .NET Windows Forms, ASP.NET, WPF and all other .NET target platforms. It can be activated with a few clicks in Visual Studio and usually requires you to insert all your strings into resX files, which are then compiled into satellite assemblies.
Angular offers the i18n attribute to highlight text to be translated, and the xi18n tool to extract these strings to an XLIFF file for translation.
So far so good, but the best platform support is useless if the localization is an afterthought. We've seen many projects over the years that have been developed without localization in mind and then inevitably run into trouble when another language needs to be supported. If all your strings are somewhere in your code, unmarked and not separated, adding a new language becomes a real challenge. Finding all strings and changing or moving them to separate files is almost impossible in a larger project and will almost certainly cause many errors that only your customers will find.
So when it comes to localization a good start is everything. Think about localization before you start coding! And follow these simple rules:
Nov. 2016
Visual Studio is a very productive development environment but with regards to localization if offers very little. Localizing in Visual Studio is possible by creating resource files (.resX files) for the different target languages and then translating the Windows Forms (C# or VB.NET) or ASP.NET pages (.aspx files).