32

In general, translation methods take a key > value mapping and use the key to transform that into a value. Now I recognize two different methods to name your translation keys and within my team we do not come to consensus what seems to be the best method.

Method 1: Use full English words or sentences:

Name => Name
Please enter your email address => Please enter your email address

Method 2: Use keywords describing the situation:

NAME => Name
ENTER_EMAIL => Please enter your email address

I personally prefer method #1 because it directly shows the meaning of the message. If the translation is not present, you could fall back to the key and this doesn't cause any problems. However, the method is cumbersome when a translation changes frequently, because all the files need to be updated. Also for longer texts these keys become very large. This is solved by using keys like ENTER_EMAIL, but the phrasing is completely out of the context. The list of abstract translation keys would be huge, you need meta data for all the keys explaining their usage and collisions can occur much easier.

Is there a best of both worlds or a third method? How do you use translation keys in your application? In our case it is a php-based webapplication, but I think above problem is generic enough to talk about i18n in general.

Jurian Sluiman
  • 13,498
  • 3
  • 67
  • 99
  • Interesting question. I tend to favour #1 as well, but go hybrid when the situation warrants it. – Ja͢ck May 18 '12 at 14:06
  • 1
    I prefer #2 with the requirement, of course, that there is ALWAYS an English (or original language) entry. Each record should also include a date/time for when it was last updated to point out messages that have changed and the need for updated translations. Separately, a record should be stored that tells what the original language is. – Jonathan M May 18 '12 at 15:23

2 Answers2

25

This is a question that is also faced by iOS/OSX developers. And for them there is even a standard tool called genstrings which assumes method 1. But of course Apple developers don't have to use this tool--I don't.

While the safety net that you get with method 1 is nice (i.e you can display the key if you somehow forgot to localize a string) it has the downside that it can lead to conflicting keys. Sometimes one identical piece of display text needs to be localized in two different ways, due to grammar rules or differences in context. For instance the French translation for "E-mail" would be "E-mail" if it's a dialog title and "Envoyer un e-mail" if it's a button (in French the word "E-mail" is only a noun and can't be used as a verb, unlike in English where it's both a noun and a verb). With method 2 you could have keys EMAIL_TITLE and EMAIL_BUTTON to solve this issue, and as a bonus this would give a hint to translators to help them translate correctly.

One more advantage of method 2 is that you can change the English text without having to worry about updating the key in English and in all your localizations.

So I recommend method 2!

Clafou
  • 15,250
  • 7
  • 58
  • 89
  • Your example of `EMAIL_TITLE` and `EMAIL_BUTTON` is a very good one, however I don't think this is a realistic one. As English developer, you don't know this French case. So you write `E-mail` (#1) or `EMAIL` (#2) in the first place. Then your French translator comes back with the message he needs two keys, so you change the button into `E-mail (button)` (#1) or `EMAIL_BUTTON` (#2). The process for both methods is the same, in the end you have a collision and you need to solve that. What's your thought about this? – Jurian Sluiman May 19 '12 at 11:19
  • 2
    Developers need to be aware of a few internationalization rules. They don't have to know a particular language, just that, in this case, a piece of text cannot be expected to be reusable in different contexts (even where it's not a problem in English). So while developing your app, when you introduce a new string for an "Email" button, you add an entry to your string table even if you see that you have "Email" already but for a different context. – Clafou May 20 '12 at 11:03
  • Note that for many platforms this non-reuse rule is helped by the fact that UI views are localized in bundles and you don't write code to load each piece of text from string tables (so you often get multiple instances of a same piece of English text to translate, but that's OK as their context may be different) – Clafou May 20 '12 at 11:03
  • Finally we're going for method #1, but I am going to accept your answer (since everything is explained nicely). With gettext we scan now the complete code base. If an English sentence has been changed, it is automatically updated in the gettext files. We can also copy over the key to the value with POedit much easier than expected. We haven't hit the constraints you mentioned, but that is perhaps because we're only in English, Dutch, German and Russian and have no French version yet. We'll see what happens if we ask our translators :) – Jurian Sluiman Oct 31 '12 at 16:23
  • See also http://stackoverflow.com/a/13978656/470749 E.g. it might be a link to a social network, and in US it would be Facebook but in China it would be Weibo. So the MsgIds might be something like socialSiteUrl and socialSiteLabel. – Ryan Jan 29 '13 at 21:26
4

Why not use both worlds? I use method #1 for short strings, and method #2 for long strings that are full sentences. I am not afraid to mix both in the same file.

For example, in the following string the text may change if in a new app version the user experience is modified:

"screen description" = "Tap the plus button to add a new item. Tap an item for more options or to edit its details.";

So here it makes sense to apply method #2. However, for simple strings like in the following example, method #1 is more useful:

"Preferences" = "Preferences";

In general when people try to standardize things it often appears restrictive to me. Personally, I prefer a more "anarchistic" approach where several methods are valid (not only as in this method #1 vs method #2 thread, but also for example when a team of developers fight over coding style).

bio
  • 669
  • 4
  • 14