Recently we have been internationalizing (aka i18n, l10n) our website Traxtuff. Like most programmers we began by producing a detailed design of our dream translation framework for PHP, but a quick search in google made us choose gettext. There are many good articles about using gettext with PHP(Here's one and here's another, Pablo Hoch also posted a benchmark of gettext). Even though it's far from perfect, it's widely used in many projects, so we decided to use it. We added some nice helper functions to wrap _() (aka gettext()):
function _L($str)
{
echo _($str);
}
function _S()
{
if (func_num_args() == 0) {return;}
if (func_num_args() == 1) {_L(func_get_arg(0));return;}
$args = func_get_args();
$args[0] = _(func_get_arg(0));
echo call_user_func_array('sprintf', $args);
}
function _T()
{
if (func_num_args() == 0) {return false;}
if (func_num_args() == 1) {return _(func_get_arg(0));}
$args = func_get_args();
$args[0] = _(func_get_arg(0));
return call_user_func_array('sprintf', $args);
}
Don't ask what L, S & T stand for, I just chose letters randomly :) .
We then had to decide what to do with internationalized strings inside our javascript files. I bumped (completely by accident while researching something else) upon a cool implementation of gettext for Javascript. Here is a link to it. I admit it's not very well documented (major understatement), but it's pretty simple to use. To get the code you need to go into the code repository here. This code depends upon the ubiquitous prototype javascript framework. Basically what you need to do is add in your HTML a link to your po (POT) file:
<link rel="gettext" lang="de" href="[path to your po file]"></link>
And after it in your scripts:
Gettext.lang = 'de';
Gettext.gettext('hello %s','world');
_('hello %s','world');
Yonatan couldn't make this work, so he added before this the code:
Gettext.include.apply(Gettext, Gettext.links[Gettext.linksPointer]);
Gettext.linksPointer++;
Hope this works for you. Let us know if you find something more elegant.
Everything was working peachy, until we upgraded to prototype 1.6. I spent a few hours today trying to figure out why gettext.js stopped working. Finally it turned out that the prototype function Array.indexOf doesn't work in the same way (hope I'm not saying something stupid). Previously it supported finding elements in an array like this:
var arr = [["a"], ["b"]];
arr.indexOf("a");
But now it only supported flat arrays (I think this is because prototype.js first checks if the browser already has an implementation of Array.indexOf). So I fixed gettext.js by adding flatten() call before calling indexOf for the message arrays. It's just a small change in 2 places, so it's not too scary :).
That's all, happy hacking for all of you.
p.s. We recommend creating a separate po files for your javascripts, so it will be as small as possible. After all this gettext implementation isn't very efficient.