Links

Monday, 25 January 2016

Internationalization (i18n) and Localization (l10n) of Keycloak

Keycloak's admin console needs to be fully localized. That is, we
need to replace all of our static English text and replace it with
something that can display readable text in the user's local language.
I've done this sort of thing many times in Java, but our admin console
is written in AngularJS, which is rather new to me.

So I set out to discover what i18n/l10n libraries might help. I found three candidates.

angular-translate
is very similar to angular-localization. angular-translate's founder
and primary author is Pascal Precht. "Pascal" is a phenomenal name for a
programmer, so his library must be good. But just to check, I did watch a talk,looked at GitHub, and the docs. This one would get a test-drive too.

Among the three, angular-gettext wins the award for best web site.
But beyond that, I didn't like what I saw. The approach is completely
different from the first two. You annotate your code and run it against
a tool that tries to figure out where the static text is. Then it uses
the English text as keys to put into .po files for translation.
Magical! But as any Harry Potter fan knows, while magic can be fun, it
can also go horribly wrong.

The more I read about
angular-gettext, the more it just didn't seem right for Keycloak. I
hate an over-reliance on tools. I don't like forcing developers and
translators to learn new tools either. Plus, I don't think our
translators ever use .po files.

Maybe I was punting on third down*, but I just couldn't justify spending more time on angular-gettext.

(*Note that "punt on third down" is an American football reference that that can not be localized to soccer. :-) )

angular-localization vs angular-translate

So it's down to two
candidates. To try these out, I created a simple app that localizes the
Keycloak login page. In Keycloak today, this page is already localized
using Freemarker. But for this exercise I just grabbed the raw HTML
and created two AngularJS pages, one to test each library. You can see
the code or try it yourself. I've uploaded the source to my GitHub account.

Here is how it looks with both libraries. Both allow you to change languages with the press of a button:

So both libraries work, and the code I had to write for each is very similar.

Here is a simple translation for angular-localization:

<label for="password">{{'password' | i18n}}</label>

Here is the same translation for angular-translate:

<label for="password">{{'password' | translate}}</label>

Both
let you do translations with directives or filters. Both use JSON
resource bundles for translation mapping. Both let you parameterize
your messages, and both have support for AngularJS features like
pluralization and two-way binding. Both meet Keycloak's requirements.

So which do we choose?

The maturity heuristic

There are indeed some technical
differences between the two libraries. And judging from what I've seen,
angular-localization probably learned some things from its older, more
mature cousin. But therein lies the rub. angular-translate is
considerably more mature.

The great thing about open
source is that I can assess this maturity. It's quick and easy to look
under the hood and see how far along a project really is. You can see
the frequency of commits. You can see the diversity of the developers
who have submitted pull requests. And most important, you can see if
the project is still "alive" with recent commits and releases.

In
other words, you can assess the community. Software is only as good as
the company or community that stands behind it. So in the end, the
choice was pretty easy. We went with angular-translate.