4

I'm using gettext for internationalization for my php files. I have two servers; a sandbox server and a release server. in sandbox server a directory like locale/LC_MESSAGES/en does not work and I should use locale/LC_MESSAGES/en_GB instead. But with "en_GB" it doesn't work on my production server and "en" works fine. for some languages like Portuguese I have pt_PT and pt_BR (Brazilian Portuguese). So I prefer to use the "A_B" structure.

I have no idea how gettext detects these folders. Is there a standard way to use the same folder structure?

MKoosej
  • 3,405
  • 3
  • 21
  • 29

1 Answers1

5

If you're running your code on Linux, gettext works only with locales already installed on the OS. This means that if you set the locale to en_GB then if the only installed locale is en_GB.utf8 or en_US, then you don't get the translations.

Try this on both of your environments and compare the results:

locale -a

It gives you a list of all the installed locales:

en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_GB
en_GB.utf8
de_DE

de_DE.utf8
C
POSIX

Now you need to make sure that both of the environments have the same locales installed; If you need en_US.utf8, en_AU, and en_AU.utf8, you can create the missing locales based on an existing one (read localedef manpages to know the details):

sudo localedef -c -i en_US -f UTF-8 en_US.utf8
sudo localedef -c -i en_GB -f UTF-8 en_AU
sudo localedef -c -i en_GB -f UTF-8 en_AU.utf8

Also, what follows is the common best practice for using gettext on PHP:

<?php

    // Set language to German
    putenv('LC_ALL=de_DE.utf8');
    setlocale(LC_ALL, 'de_DE.utf8');

    // Specify location of translation tables
    bindtextdomain("myPHPApp", "./locale");

    // Choose domain
    textdomain("myPHPApp");

    // Translation is looking for in ./locale/de_DE.utf8/LC_MESSAGES/myPHPApp.mo now

    // Print a test message
    echo gettext("Welcome to My PHP Application");

    // Or use the alias _() for gettext()
    echo _("Have a nice day");

?>

Although you can simply drop the encoding and just de_DE, but it's a good practice to have the character set in the locale as in some specific cases you might need to support content in non-Unicode character sets. See below

<?php

  // Set language to German written in Latin-1
  putenv('LC_ALL=de_DE.ISO8859-1');
  setlocale(LC_ALL, 'de_DE.ISO8859-1');

?>
Shervin
  • 1,936
  • 17
  • 27
  • Thanks for your complete response Shervin! Although I have not a secure shell access to my server to run these command but I will try with echo setlocale(LC_ALL, 0); in my php script instead. I'm also worried about other processes changing locale I read some stuff about it and we have some python and rails app. Is locale is a system wide parameter or just tied to php/apache process? – MKoosej Aug 19 '13 at 13:04
  • You're very welcome. Actually, `putnev()` is limited to the current request and `setlocale()` is limited to the current script. These don't affect the OS or other processes. After the script is done running, the values are return to the defaults. That's why the language should be maintained through the session in some other way. – Shervin Aug 20 '13 at 03:54
  • 1
    Nice answer! Note: "`setlocale()` is limited to the current script" -- I guess that also (practically) means the current _request_ instead (the PHP execution context, actually), not just the script, so if you include another script, or you include this one from another, you don't need to set the locale in every PHP file (script). – Sz. Jun 23 '14 at 19:44