Localization: Is your application ready for? A checklist

If an application should be localized, then it is necessary that everything is prepared.
I would like provide a checklist now.
(Well it is a hard work to look into every source file and check everything, therefore it would be better to keep the list in mind until developing. Afterwards the whole application automatically is prepared)

  1. Language dependent methods have use the CurrentCulture
  2. No hardcoded strings
  3. Let enough space for string expansions
  4. Set the CurrentCulture and CurrentUICulture every time
  5. Let the UI be completely changeable without modifications on the code
  6. Don’t work with the strings themselves
  7. Use named placeholders
  8. Don’t concatenate strings
  9. Don’t change other translations

I would write some notes to every point now, what I mean with them.

1. Language dependent methods have use the CurrentCulture
There are some methods which will be different in the cultures, for example the display of a numeric value.
We have the value

double val = 1.5;

In German it is normal to use the comma as a separator: 1,50, in some other cultures they want to use the dot: 1.50.
Bad:

val.ToString()

Good:

val.ToString(CultureInfo.CurrentCulture)

The same on the way back, if we get a number value as a string, we have to parse it correctly.
Bad:

double.TryParse(otherValue, out val)

Good:

double.TryParse(otherValue, NumberStyles.Float, CultureInfo.CurrentCulture, out val)

Next example, date values: In German we write .., in some other languages the date has to be <Month>/<Day>/<Year> or <Year>-<Month>-<Day>.
Bad:

DateTime.Now.ToString();

Good:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

And the way back
Bad:

DateTime.TryParse(otherValue,  out val)

Good:

DateTime.TryParse(otherValue, CultureInfo.CurrentCulture, DateTimeStyles.None, out val)

Therefore, please every time if an output differs and such a string has to be parsed, use the correct output or parsing value.

2. No hardcoded strings
Strings directly in the cs or xaml files are bad at all, they has to be read from the resources.
Bad:

<TextBlock Text="Hello World" />

Good:

<TextBlock Text="{DynamicResource General_HelloWorld}" />

3. Let enough space for string expansions
The WPF UI can be very dynamic, TextBlock can expand automatically by its needed space by the content, but that isn’t possible every time, therefore please keep in mind: Let enough space for longer translations of a string.
It is a good rule to say: There has to be enough space for a longer string with 30% more characters from the original. For single words like “Rip” please let enough space for the English string 2-3 times.
(“Rip” can be “Aufnehmen” in Germany)
“Be Dynamic” means, no value for Width or Height, only Min** or Max** values can be set by meeting the expansion rule.
Bad:

<Button Width="50" Text="{DynamicResource General_Cancel}" IsCancel="True" />

Good:

<Button Padding="10,1" Text="{DynamicResource General_Cancel}" IsCancel="True" />

Let WPF do its work and determine the needed spaced by itself.

4. Set the CurrentCulture and CurrentUICulture every time
On application start the CurrentCulture and CurrentUICulture of the application have to be set to the correct culture, otherwise the methods from point 1 will not work as expected.
Note: The BackgroundWorker does not take it from the application.

Thread.CurrentThread.CurrentCulture = new CultureInfo(Settings.Instance.Language);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
					System.Windows.Markup.XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.IetfLanguageTag)));

5. Let the UI be completely changeable without modifications on the code
Germans would like to see everything in one look, Asian would like to click much more, therefore a correct full localized application should have completely different looks of an application.
For that I suggest to use the MVVM Pattern and don’t call anything from the UI directly, simply provide all information of the Models in the ViewModels, and let the UI’s do they work, then it can be switched to a completely new UI at runtime without developing different code for each UIs.

6. Don‘t work with the strings themselves
Please don’t work with the strings themselves:

if (value == "Yes")

or

if (UserImput.EndsWith("rep"))

7. Use named placeholders
If you need a string like: “Please select files between 1. January to 1. February for a backup” and the times have to be changeable.
It’s tempting to create a string like:
“Please select files between {0} to {1} for a backup”, but please don’t do so.
It’s better to use named placeholders:
“Please select files between [TimeFrom] to [TimeTo] for a backup”
Then the translator know what will be placed in, the translation can be different depended on the placed in values. If there are only {0} and such characters, the translator has no chance to create a good translation.

8. Don’t concatenate strings
No concatenations! That’s it’s.
“Please copy files from the ” + folder + “ to the target”
This can’t be translated at all. In many languages it will be completely different translated.
“Please copy files from the “ is not a base for translators, he don’t know what will follow, and sometimes he can’t translate it because of the fix position.
In such a case, use named placeholders.
“Please copy files from the [Folder] to the target”.

9. Don’t change other translations
If you have a string translated
“This is an information about NickShedule”
(NickShedule is the application name)
And you will change the application name, don’t do it in the target translation yourself.

English has a good example
We can say
“An NickShedule”, but if we replace the name by “SomeShedule” the string hast to be
“A SomeShedule”, you see, such changes like the English “An” and “A” also exist in other languages.
Sometimes the word position also differs.
Therefore, don’t change target languages if you don’t have enough knowledge for.

David W.

Comments are closed.