Gettext not translating PHP in Debian 10

Viewed 308

I'm trying to localize my website, it is located in a VPS running LEMP Debian 10 (PHP 7.3.27-1~deb10u1). I have spent the day troubleshooting why it's not working with no success.

My project has the following structure:

MY_PROJECT_NAME
   - locale
       - en_GB
            LC_MESSAGES
               en_GB.mo
               en_GB.po
       - es_ES
            LC_MESSAGES
               es_ES.mo
               es_ES.po
   - index.php

The file index.php has the following code:

<?php

session_start();
$language = "es_ES";

if (isset($_GET['language']))
{
    $language = $_GET['language'];
}

putenv("LANG=" . $language);
putenv("LC_ALL={$language}");
setlocale(LC_ALL, $language);

$domain = $language;
bindtextdomain($domain, "./locale/");
textdomain($domain);
bind_textdomain_codeset($domain, 'UTF-8');

var_dump( file_exists("./locale/$language/LC_MESSAGES/$language.mo" ) ); //bool(true) if exists
echo ('<br/>');
echo $language; //output the lang name
echo ('<br/>');
echo gettext('hello'); //text to be translated

?>

The content of file es_ES.po is as follows:

msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-05-28 00:19-0500\n"
"PO-Revision-Date: 2021-05-28 01:54-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.3\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: es_ES\n"

msgid "hello"
msgstr "Hola mundo"

and the file en_GB.po has the following content:

msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-05-28 00:16-0500\n"
"PO-Revision-Date: 2021-05-28 01:54-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.3\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: en_GB\n"

msgid "hello"
msgstr "Hello word"

Both files has been compiled with POedit, to generate the correct .mo files.

Also, i have added the locales to the system via sudo dpkg-reconfigure locales. The output of the command locale -a is the following:

C
C.UTF-8
de_DE.utf8
en_GB.utf8
en_US.utf8
es_ES.utf8
it_IT.utf8
ja_JP.utf8
POSIX
pt_BR.utf8

Whenever i run the php code to check if the translation works: index.php?language=en_GB index.php?language=es_ES

I get the output:

bool(true)
en_GB
hello

and

bool(true)
es_ES
hello

Respectively. What am i missing? There is no error in the logs, i have rebooted the server to makie sure it's not a cache issue, also i have tried several variants of the index.php configurations with no success.

2 Answers

I believe the confusion is that you're using a dynamic domain, based on the language, while the domain is fixed and represents the filename of the translation.

So first of all, reorganise your files as follows

MY_PROJECT_NAME
   - locale
       - en_GB
            LC_MESSAGES
               messages.mo
               messages.po
       - es_ES
            LC_MESSAGES
               messages.mo
               messages.po
   - index.php

Once the files are renamed correctly, then you can set your $domain to messages instead of the language

$domain = 'messages';
bindtextdomain($domain, "./locale/");
textdomain($domain);
bind_textdomain_codeset($domain, 'UTF-8');

This should fix your issue. Also double check that your paths are correct, and depending on how you call your index.php file, you might want to switch from the relative path ./locale/ to using __DIR__

I solved the issue by installing additional languages with sudo dpkg-reconfigure locales.

The locale en_GB.utf8 was not set when en_GB was requested by the script.

There is no plain en_GB in debian's sudo dpkg-reconfigure locales screen, the needed locale is shown as en_GB ISO-8859-1.

Related