How to build a multi-language web site


A friend of mine is now building a web application with J2EE and Struts, and it's going to be prepared to display pages in several languages.

I was told that the best way to support a multi-language site is to use a properties file where you store all the strings of your pages, something like:

welcome.english = "Welcome!"
welcome.spanish = "¡Bienvenido!"

This solution is ok, but what happens if your site displays news or something like that (a blog)? I mean, content that is not static, that is updated often… The people that keep the site have to write every new entry in each supported language, and store each version of the entry in the database. The application loads only the entries in the user's chosen language.

How do you design the database to support this kind of implementation?


Best Solution

Warning: I'm not a java hacker, so YMMV but...

The problem with using a list of "properties" is that you need a lot of discipline. Every time you add a string that should be output to the user you will need to open your properties file, look to see if that string (or something roughly equivalent to it) is already in the file, and then go and add the new property if it isn't. On top of this, you'd have to hope the properties file was fairly human readable / editable if you wanted to give it to an external translation team to deal with.

The database based approach is useful for all your database based content. Ideally you want to make it easy to tie pieces of content together with their translations. It only really falls down for all the places you may want to output something that isn't out of a database (error messages etc.).

One fairly old technology which we find still works really well, is to use gettext. Gettext or some variant seems to be available for most languages and platforms. The basic premise is that you wrap your output in a special function call like so:

echo _("Please do not press this button again");

Then running the gettext tools over your source code will extract all the instances wrapped like that into a "po" file. This will contain entries such as:

#: myfolder/my.source:239
msgid "Please do not press this button again"
msgstr ""

And you can add your translation to the appropriate place:

#: myfolder/my.source:239
msgid "Please do not press this button again"
msgstr "s’il vous plaît ne pas appuyer sur le bouton ci-dessous à nouveau"

Subsequent runs of the gettext tools simply update your po files. You don't even need to extract the po file from your source. If you know you may want to translate your site down the line, then you can just use the format shown above (the underscored function) with all your output. If you don't provide a po file it will just return whatever you put in the quotes. gettext is designed to work with locales so the users locale is used to retrieve the appropriate po file. This makes it really easy to add new translations.

Gettext Pros

  • Doesn't get in your way while coding
  • Very easy to add translations
  • PO files can be compiled down for speed
  • There are libraries available for most languages / platforms
  • There are good cross platform tools for dealing with translations. It is actually possible to get your translation team set up with a tool such as poEdit to make it very easy for them to manage translation projects

Gettext Cons

  • Solves your site "furniture" needs, but you would usually still want a database based approach for your database driven content

For more info on gettext see this wikipedia page

Related Question