Archive for November, 2010

Localization: Tricky issue

November 11, 2010

Vernacular localization: Tricky issue

For a foreigner living in Germany there are several cultural and vernacular differences that you notice straight away, and several more subtle ones that take a while for you to realize, even though they have been staring you in the face the whole time.

Something that is important to get correct from the start is time-keeping. 7:30 is called “halb acht” in German, which translates as “half eight”. While it first appears that the Germans are calling it half to eight instead of half past eight, the reality is they’re saying half of eight. This allows constructs like “drei viertel acht” or “three quarters of eight” for 7:45, and “fünf vor halb acht” or “five to half of eight” for 7:25. This seems perfectly normal in Germany. Eventually. There are several other time-based peculiarities in German, such as the word for “tomorrow” being the same as the word for “morning” (“morgen”), so that if you want to say “tomorrow morning”, you have to say “early tomorrow” (“morgen früh”), whereas if you want to say “this morning”, you have to say “today morning” (“heute morgen”).

Date handling in Germany is standardized in dd.mm.yyyy format instead of dd-mm-yyyy or dd/mm/yyyy. At least it’s not mm/dd/yyyy, which is the bane of my life. Anytime I see 4/6/2010 I have to look for more dates on the same page or document until I find one where the first or second element is greater than 12, or I will have no idea whether it’s an April or June date.

When the number 100.001 is written in English speaking locales it (usually?) means “one hundred point zero zero one”, whereas in Germany, it means “one hundred thousand and one”. 100,001 in Germany means “one hundred point zero zero one”. For a reason I can’t grasp, the German and English localization systems evolved to use exact opposite characters for thousands separation and decimal separation.

Something I didn’t notice until this week though is that currency formatting differs between Ireland and Germany. In Germany the Euro symbol is put after the amount (Except in a badly localized flash ad that’s there now), but in Ireland the symbol is in front of the amount.

Literal or near-literal translation brings more entertainment. Most German people I know have a Chef that they see most days of the week, but who does not cook for them. How’s that for a false friend?

Although most simple sentences similar to “I am hungry” can be translated to “Ich bin hungrig”, it is not correct to translate “I am cold” as “Ich bin kalt”, because that means “I am a cold-hearted person”. Instead it must be “Mir ist kalt”. In the same vein, “How are you” – “I’m good” doesn’t work in German. The “Ich bin gut” means “I’m a morally good person”, which is a non-sequitur in this context. The answer has to be “Mir ist gut” or “Mir geht’s gut”. I also found out that when a waiter asks if I’d like another beer, and I don’t, “No, I’m Ok” doesn’t translate to German very well. Sometimes these things are discovered when the reply is laughter and a “Yeah, we think you’re ok too Steve…”.

My old favorite German term is “krass”, which is pretty much an emphasizer, usually I hear it as a negative, but can be used in a positive too. The weather can be krass. A movie can be “krass lustig”. The best (“krasste”?) moment for krass was when a friend of mine described a particular situation as being “krass krass”. My new favorite German phrase is “Der Hammer!”. Der Hammer is the best thing there is. In en_US that would be ‘Da Bomb!’ I guess.

Gut > Besser > Am Besten > Der Hammer

On top of all the peculiarities and differences in expression, native speakers of English living in or visiting Germany are called “native speakers”. To me “native” means “indigenous to the current geography”, so I still find that a bit weird.

It’s not that English doesn’t have it’s fair share of peculiarities. Why does inflammable mean flammable, for a common example? Even within English there are wild deviations from the norm. That’s a great article by the way. If you want to know what “long monophthongs are often dipthongized, and while some diphthongs are tripthongized” means, take a break from the MeeGo conference and go to Moore Street for “Bananids five for a pow-und”. A notable omission from the Lexicon on the page though is ‘fierce’, which translates to German as approximately ‘krass’. With all that, it’s not uncommon for natives of the Queens English to have problems understanding Hiberno-English, and not just because of the accent. Check this Video with NSFW Audio to more from the Wexford Lexicon without the accent and see if you can make any sense of it.

The point is that localization issues are things we encounter everyday, within and without computer systems but they have to be handled in computer systems too.

Mann, eh?

Abstract localization: Tricky issue

For Qt developers the first thing localization means is a choice. Do the Qt built-in localization facilities meet the applications needs? Would gettext be different? Can KLocale be used instead? The answer to all three is, of course, Yes. Qt localization is quite extensive for most Qt developers which don’t target very uncommon locales. KLocale is a more powerful localization system, and is part of the KDE platform which can be used without many extra dependencies than QtCore and gettext, which it extends.

Of course, KLocale and Qt localization systems are incompatible – They use different conventions in strings for plurals and different forms of catalogs, so a Qt developer has to pick one up front. For developers of libraries like Grantlee, that brings a need for abstraction. Grantlee now features an AbstractLocalizer which can be implemented to support any localization system. I’ve already implemented it for QLocale and for KLocale. That means that Grantlee templates can now be localized easily in both Qt applications and KDE applications.

We have a joke in the Grantlee community there are so many examples distributed in Grantlee for text editing, code generation etc that KDE is almost obsoleted (har-har). To test out the l10n feature I’ve added an address book application:

Contacts with plurals en_US

Contacts with plurals

Contacts with plurals de_DE

There are several important things to note here:

  • I suck at creating good looking html
  • Strings are translated
  • Strings with plural forms are translated
  • Numbers are localized properly. The German version uses comma for decimal separation.
  • Money is localized properly. The German version puts the Euro symbol on the right.
  • Dates are localized properly. The en_US version is wrong, and the German version uses dots for separators.

    The localization supports all of the common localization needs for application development.

  • Using _() to localize strings: {{ _(“Table of contents”) }}
  • Using _() to localize anything: {{ _(some_date_variable) }} where some_date_variable is a QDate outputs 14/3/2010 in en_GB, 3/14/2010 in en_US, and 14.3.2010 in de_DE. Numbers like {{ _(100001) }} are also localized properly.
  • Using i18n for argument substitution: {% i18n “Hello %1, Welcome to %2” username website_name %}
  • Using i18nc for disambiguated localization: {% i18nc “Name of a person” “Name” %}, {% i18nc “Name of a category” “Name” %}
  • Using i18np for plurals: {% i18np “%1 person” “%1 people” numPeople %}
  • Using i18ncp for disambiguated plurals {% i18ncp “The amount of people logged in” “%1 person” “%1 people” numPeople %}
  • Using l10n_money to localize monetary values: {% l10n_money amount “EUR” %} outputs for example, “€ 99.99” in the Irish locale, and “99,99 €” in the German locale.

    Isolated localization: Tricky issue

    Usually if you are creating content, the content is created in the locale the application is running in. For example, I can export address book entries from KAddressBook and birthdays will be formatted as 20/11/2009. If I want to export the address book entries and send them to a German person it should be localized for Germany. To do that I would have to restart the application with the correct locale or switch my system locale. With Grantlee and AbstractLocalizer it is now possible to construct a localizer with the appropriate QLocale or KLocale and the exported document will be correctly localized.

    So if you use Grantlee to export content you can let the user decide what locale to target when exporting.

    Mixed localization: Tricky issue

    When learning a language it can be helpful to see the same terms and phrases in the same place in different languages. By using Grantlee for theming you can now allow users to use multiple locales/languages in the same rendering.

    Tables in multiple locales

    Table with multi-lingual header

    Admittedly, I only added this feature because I wanted to see if it would be possible. I don’t know if anyone would use it.

    Extended localization: Tricky issue

    The whole point of Grantlee is to enable accessors to become mutators – enable users to create and share themes for applications like KAddressBook, KMail etc. Those themes will have to be localized, even if the theme introduces strings which were not already in the original application. Now themers will be able to custom create themes and even add custom fields which can be translated. The translations of course would need to be shipped with the theme.

    In this example, a themer has added a calculation to the theme (in javascript, because we can) for the age/salary ratio.

    Theme with age/salary ratio en_US

    This can then be translated and localized easily:

    Theme with age/salary ratio de_DE

    Localization: Easy

    i18n/l10n has been on the roadmap for Grantlee since day one. I started working on this at Akademy in Tampere, and am only nearly finished now. It took a few attempts to get the design right and learn everything needed about localization in general and computerized localization in particular. Now it’s easy for everyone else. 🙂

    All of this works of course with “pure” Qt and with KLocale and the extensions it provides.

    BTW for more on the elite Germans of Berlin check out Wash Echte.

  • MeeGo@Dublin

    November 9, 2010

    I’ll be in Dublin on Monday only for the first day of the MeeGo conference at Lansdowne Road.

    Try to catch up if you want to talk about things I know about such as Qt ModelView, string templating, QML, KDE, PIM or KDAB.

    I’ve also been getting more interested in state machines and l10n/i18n lately, so they’re also good topics.

    Watching my Ks and Qs

    November 1, 2010

    The good thing about transatlantic flights is that it gives me an opportunity to watch movies on a tiny screen that I otherwise wouldn’t watch at all. On my outbound flight to the US last week I managed to watch Shrek and most, but not all of Toy Story 3. I needed closure though. Will Woody unite the toys and save the day? Will Buzz ever be the same again? The return flight yesterday(today?) brought the closure, but also gave me some time to work on something I’ve been putting off for a while.

    I originally wrote KIdentityProxyModel with the intent of putting it into Qt on request. Once it gets into Qt I’m no longer the maintainer, so someone else in Nokia gets to decide whether to apply patches I submit to it. I needed to make sure it was as correct as possible before submitting it so it went into kdelibs for an incubation period.

    There are many style and structural differences between kdelibs classes and Qt classes. Documentation in kdelibs is usually in the header file, whereas in Qt it is always in the implementation file. In kdelibs, we use a _k_ prefix for Q_PRIVATE_SLOTS, whereas Qt uses a _q_ prefix. Easily updated with some perl dash pie. Another difference is that the protected constructor takes an instance of the private class as a reference instead of as a pointer. I only recently realized the reasons for doing it that way. Finally, In the case of proxy models, the source model is usually referred to as d->model instead of q->sourceModel(). That’s possible in Qt, but not in kdelibs because of the inheritance of QAbstractProxyModelPrivate.

    With all of those changes made I submitted the MR for the patch that mostly I wrote around the time of Akademy in July. It’s an interesting time to be submitting classes to Qt, not least because of the column inches it is getting these days. Contributors are eager to find out the extent that the Qt Open Governance model will facilitate these kinds of contributions and make them easier and sustainable.

    In a KDE context it is even more interesting. There has been lots of discussion since the end of last week about the role of the kde libraries in the greater Qt ecosystem. Do Qt developers know useful libraries are in kdelibs? How can we make those libraries easier to find, access, and use? One proposal is to attempt to submit as much as possilble of kde libraries into Qt itself. That would require dramatic changes to the current maintenance and contribution model, so it will be interesting to see where that goes.