When is localization (or lack of) a bad thing?

Viewed 208

The following code returns a message which states whether the input value is a palindrome:

(for the sake of this post, the syntax isn't important, or written in any particular language)

function isPalindrome(
    value: string, 
    successMessage: string = "Is palindrome", 
    failureMessage: string = "Is not palindrome"): string {

    return value.reverse() == value ? successMessage : failureMessage;
}

Notice in the code above, the default messages are written in English, however as they are supplied as parameters, this method could easily be localized, and because the method has default values for the messages, this doesn't force the developer to provide them; for example:

isPalindrome("level") // returns "Is palindrome"

However we can demonstrate localization; for example, in spanish:

isPalindrome("level", "es palíndromo", "no es palíndromo") // returns "es palíndromo"

This got me thinking, when should code be designed with localization in mind?

Another example would be with exceptions; for example:

class PalindromeException : Exception("Is not a palindrome")

function validatePalindrome(value: string): void {
    if (value.reverse() != value) {
        throw PalindromeException();
    }
}

Notice in this example that there is no way to localize the message in the exception. I know this could easily be fixed using the same principles in the first example, but it has been purposefully designed to demonstrate a lack of globalization.

Therefore, when should globalization be applied to code, so that it may be localized? When does it matter, and when does it not?

4 Answers

I believe, there's no ideal answer - everything depends on your architecture and use-cases.

However, I would suggest the following patterns:

  1. All log messages (both server and client) should be in English
  2. All error API responses should always provide a description in English and a unique error code which you can translate into a friendly message on the client side
  3. In order to provide a good UX, all client messages should be in a user's language

In general, it's a good practice to have all technical data (logs, errors, etc) in English. All user-facing data has to be understandable for a user.

It strongly depends on your use-case. I would recommend to localise messages, that are displayed in a frontend, right away. My experience is, it's very costly to do it later. For debugging or monitoring messages I probably would do it just in english, 'cause most of developers are able to read english messages.

All labels needs to be translated.

For this definition, text is an information being read by end user. In that context, a label is a piece of text which at the same time is not user input or user data.

To give an example, in an 'Save as' dialog the file name would be user input, the file content user data and the Save and Cancel labels on the two buttons would be the labels (and therefore in need of an translation).

Given this definition, the rule is as follows:

Only user interface code needs to translate and it translates all labels. On the opposite, business logic code not directly facing end users (such as libraries or backend services) shall not translate at all. Further, neither the business logic implementation nor the business logic API handles text other then user input or user data.

The rule thus also implicates clean separation of business logic code from user interface code. That comes very handy for testing.

For the palindrome example, the function would be business logic, and it would not return a text but something more suitable e.g. an boolean or enum. The user interface code would then evaluate the return and translate it appropriately. The same applies to the exception.

The only place where localization should take place is in the UI. If you’re sticking to the MVC principle of separation of concerns (or something similar like MVP or such), then the localization happens exclusively in the View part. Your isPalindrome function sounds more like business logic belonging to the Model part and should therefore not be concerned with i18n at all. Neither should exceptions worry about it, since no exception should ever be printed to the UI as is (except to provide debugging information, which doesn’t need to be/shouldn’t be localized).

Your function should only return true or false, and an entirely separate UI part should translate that into something user facing, potentially localizing it in the process. Same with the exception, it should be caught by something which loads an appropriately localized UI explaining the issue to the user.

Related