It’s a wonderful fact about the world that humans have thousands of living languages. And a wonderful fact about many software development environments that they provide ways to create versions of applications localized into the most common of those languages. But before localization (or should I say world-readiness) sweeps you off your feet, let me tell you about some unexpected difficulties with Kineme’s first localized application.
QuartzCrystal was translated from English into Japanese, French, Italian, German, and Spanish by a combination of Kineme users (@yanomano, @DanieleCiabba) and designers/developers (@mradcliffe, @bbinkovitz, @cwright, @smokris, and me). Localization began less than a week after the first Subversion commit, and now, 3 years later, we’re up to version 2.0. Out of all of the Subversion commits on the project, surprisingly many — 17% — were related to localization. Not an accurate reflection of effort, but it does suggest that localization is nontrivial.
The easy part
Your development environment can make it easy to localize an application’s user interface. With Xcode, it just takes a few clicks to take a nib in your native language and spawn duplicates ready for translation, or to create a .strings file where your code can look up the translation of “Sorry, error -51 occurred”.
OK. You can’t just localize an application into a bunch of languages and then forget about them. You have to test your localizations when the user interface or the translation changes, or else you’ll have problems like text falling off your buttons. The testing is the hard part – more on that in the next section. Actually updating the user interface, on the other hand, is easy enough with Xcode and ibtool.
With Xcode and ibtool, you have two choices of how to localize a nib. You can either take the nib in your native language and ask Xcode to make a copy for each localization, or you can set all the user interface text programmatically using
NSLocalizedString. Either way, you’ll ask Xcode or ibtool to create a .strings file for each localization. The .strings file holds a list of native-language strings and their translations.
Say you have a localized nib and you want to add a button to it. If you’re setting the user interface text programmatically, then all you have to do is add the button to the nib and set its title in code using
NSLocalizedString (after adding translations to all the .strings files, of course). If instead you have multiple nibs, then you’re going to have to add the same button to each one of them. Fortunately — I discovered after manually editing widgets a few times for QuartzCrystal, and messing up the nib connections in the process — ibtool has a
--localize-incremental option that lets you make changes in one nib and propagate them to the rest. So that’s relatively easy.
You know what else is easy? Doing the translation. So you want to translate “This composition has no published input parameters” into Japanese. Pop it into Google Translator and you get “この組成物は、公開されて入力パラメータを持つ”. Hooray for the internet!
… until you notice that when you translate the Japanese back into English, it’s become “This composition is published with input parameters”.
So maybe the translation isn’t totally easy. More like 90% easy, 10% impossible, maybe? 90% can be handing off the translation task to someone who knows the language — then 10% is the back-and-forth with your translators every time you have to add “just a few more” strings after you thought you were done. (For QuartzCrystal, the last user interface string was added 3 hours before release.) Or 90% easy (but slow) can be using the internet to get some words that most likely convey your intended meaning — then 10% is contriving not to sound like “all your base are belong to us”.
A few tricks for using the internet to translate… First of all, I wouldn’t recommend translating into a language you’re totally unfamiliar with. For me, I know a little Ohio Spanish1, so other Romance languages kind of slightly make sense. On the other hand, a correct Japanese sentence and a random string of Japanese characters are indistinguishable to me – so the potential for mistakes is infinite.
That said, Babel Fish or Google Translate or your other favorite translator can be a good place to start. Once you’ve translated a phrase, translate it back into your native language to make sure you haven’t been tricked. Try alternative translations (Google Translate lets you click on translated text to pick alternative words and phrases) or try rephrasing the string (“This composition doesn’t have any published input parameters”) until the translation back looks OK.
Watch out for technical terms. In Spanish, a key on a keyboard is “tecla” but an access key (sometimes used in place of “password”/”contraseña”) is “clave de acceso”. In a language dictionary, look for words marked with “computing” or “informatics”. Or consult a list of computer terms like those provided by UniLang or QMUL.
Try to find another application that’s already been translated, and copy its vocabulary. For QuartzCrystal, we added a recording feature with the metaphor of a VCR, so I could look up terms like “play” and “pause” from an already-localized video player application (VLC).
If you have a possible translation of a term that you’re unsure about, you might be able to check it with an image search. For QuartzCrystal this helped for “mouse” and “key”.
The hard part
90% easy, 10% impossible… or maybe 20% or 30% impossible, when it comes to translating into languages you don’t know extremely well.
Take Japanese. A language of subtlety and context. A language where if you say “dōmo, konnichiwa” (“Well, hello there!”), someone might decide you’re saying “Hello, Domo”. A language where “This composition has no published input parameters” gets translated by Google Translator into “This composition is published with input parameters” and “This composition is an input parameter to the public”. A language with dozens of honorific titles, separate verb forms for 3 different social situations, and 6 different levels of politeness for the word “you”.
Hmm, I’ll stick to Spanish. (A language of not so much subtlety and context. A language spoken by Zorro.) But even in Spanish there’s formal “you” and informal “you”, and they’re used differently in different regions.
Also in Spanish, punctuation is different from English. There are those upside-down question marks and exclamation points (“¿Qué pasa?”), and «» in place of quotation marks. Oh, and in French, in front of certain punctuation marks you’re supposed to put a space (“Quelle night !”).
And then there are decimal points and thousands separators.
And then there are calendars.
And then there’s right-to-left text and its effect on interface layout.
And then there are character encodings. For part of QuartzCrystal, we chose a non-Unicode font, without thinking about how it would affect the localizations – until we noticed characters rendering as boxes. We ended up stripping the diacritics off of some French and Spanish words, and rendering the Japanese in Romaji.
And then there’s consistent use of terminology. The last-minute Japanese translation that Google Translate and I did of “This composition has no published input parameters” ended up conveying the correct meaning, according to @mradcliffe, but he pointed out that it used a different word for “composition” than he used in the rest of the translation. Though maybe, since anyone using QuartzCrystal would also be using Quartz Composer, which is not localized, the most consistent choice would have been to keep “composition” in English.
And then there’s the issue of completeness. Are you going to localize every single user-facing string? (For QuartzCrystal, the graphical interface is mostly localized but the command-line interface isn’t.) Should you localize error messages printed to Console? Keyboard shortcuts? Documentation on the website?
As an example of how incomplete localization can confuse the user, Google Maps in Spanish works if you use Spanish keywords (“de Athens, OH a Marietta, OH”) but not English keywords (“from Athens, OH to Marietta, OH”), whereas Google Search in Spanish only works if you use English keywords (“Kineme OR Kosada”, not “Kineme O Kosada”). (Adding to the confusion, Google Maps lets you drop the “from” keyword in English but not the “de” in Spanish.)
Another difficulty of localization is making sure that the user interface looks OK in every language. Take this button on the submission form for the Kineme composition repository (localization courtesy of Drupal):
“No file has been” what??
Or this button from Weather Underground:
“Selection of” what??
We had the same problem in QuartzCrystal. We had to make buttons and text fields wider, and sometimes even extend text fields to multiple lines. (Thank you, German.) As a rule of thumb, Jakob Nielsen suggests allowing 50% more room for localizable text than English text, but don’t rely on that — “Play” in German is “Wiedergaben”.
Earlier I mentioned two options for localizing a user interface – a single nib with programmatic localized text insertion, or multiple localized nibs. Since QuartzCrystal has one window one way and another window the other way, I got to compare the two options. With a single nib, you have to make every widget as wide as the widest localized text, but you end up with a uniform look across localizations. With multiple nibs, you can size widgets to fit each language. I preferred using multiple nibs (don’t forget ibtool
--localize-incremental) because you could see right there in Interface Builder, without having to run the application, whether the text would fit. The multiple-nib options also precludes a problem we had with the single-nib window, which was that one widget was showing English text initially; only later when its state changed did it present the localized text.
Now for the worst part about localization. The worst part is that it makes you resistant to change.
QuartzCrystal 2.0 was almost ready to release. It had already been translated, and @smokris, @cwright, @bmellen, and I were doing some testing. One of us suggested adding an auto-save feature that would save the user’s work when a certain window was closed. The suggestion was good and the code would be straightforward — it should have been no problem. But there was a problem — because we wanted to pop up an alert if the auto-save failed, and the alert had text to be localized. What would you do in this situation? Bother each of your translators with “just a few more” strings to translate? (It happened several times that there were “just a few more”.) Do the translation yourself? Skip translation for this alert? Skip the alert altogether?
Localization makes incremental changes expensive. If you’re a big company where changes entail a lot of bureaucracy anyway, then maybe you won’t see the difference. But if you’re a little company like ours with 1 or 2 developers on a project, and no notion of a pre-release code freeze, it really affects your modus operandi.
If you’re not willing to let localization block changes or releases, then an alternative is to make each release in your native language only. Then get it translated — now that the code is frozen — and re-release. For QuartzCrystal, we plan to include corrections to the version 2.0 translations in version 2.1.
Is localization worth it?
“Never again” – I said this multiple times while working on QuartzCrystal 2.0, about localizing any more of our projects. Why localize an application written in English, anyway? Not to assume that anyone in the world will understand English if only it’s shouted loudly enough – but a lot, lot, lot of people in the world speak English. About a quarter of internet users use English as their first language, and presumably a much higher proportion speak English as a second or foreign language. For QuartzCrystal, all of our users are already using the English-only application Quartz Composer, and many of them are using the almost-English-only Kineme forums. None of our other products are localized. Are those 17% of commits related to localization on QuartzCrystal a pointless effort?
And even if not, what about the chosen languages for QuartzCrystal – German, Spanish, Japanese, French, and Italian? If we are going to localize, shouldn’t we focus our efforts on the 2nd most popular language among internet users – Mandarin Chinese? Well, if you look at the demographics of registered Kineme users (those who volunteered the information, anyway), the most common places of origin are the Anglosphere, Western Europe (as in, not the Eastern Bloc), and Japan. If that’s an accurate depiction of current and potential QuartzCrystal users, then our choice of languages makes sense. (Except that we forgot Portuguese!) Although… if we started offering forums, documentation, and products in Mandarin, would those statistics change?
When I was testing the localizations for QuartzCrystal, I ended up leaving my computer’s language on Spanish all the time. That’s been really educational, not just to practice the language, but to start changing my mind on what I said about localization – “Never again”. It’s hard using an application written in a language you’re not fluent in. I switched my default web browser shortly after switching the language to Spanish, and even though it’s just another browser I still don’t know what some of the menu options mean. Using applications and websites in a language I’m not fluent in isn’t infeasible, but it’s often slow and frustrating.
I don’t have any good answers yet on how to decide when localization is worthwhile – if you do, please post a comment – but I can advise you that it’s not as easy as selecting the “add localization” option in Xcode and popping strings into Babel Fish. So before leaping into world-readiness, ask yourself: Is there something that will make localization easier for you — like an in-house person fluent in multiple languages, who’s likely to be around for the lifetime of the application? Is there something that will make it harder — like a tendency to make last-minute user interface changes? I’m skeptical that localization was worthwhile for QuartzCrystal, but I’m open to it for future projects.
Ohio Spanish — Textbook Spanish spoken with an Ohio accent. Not unlike Ohio tacos, which are made of cheddar cheese, iceberg lettuce, and canned refried beans, and served with Old El Paso salsa. ↩