gettext in php always returns input string - php

I need to get my php code multilingual. The translations are POEdit.com exports.
Because I want to display single and plurals I have to use gettext (the php array export of POEditor does not support plurals).
My problem:
Gettext does always return the input string (msgid), not the translated text.
My setup:
Windows 7 64-Bit german system locale
EasyPHP Devserver
Apache 2.4.18
PHP 5.6.17 + gettext enabled
Folders and Files:
web root = C:\Users\SM\PhpstormProjects\website
locales = C:\Users\SM\PhpstormProjects\website\src\i18n
polish translation = C:\Users\SM\PhpstormProjects\website\src\i18n\plk\LC_MESSAGES\messages.mo
PHP Code:
define('_LOCALES_DIR', 'C:\Users\SM\PhpstormProjects\website\src\i18n');
$locale = "plk";
$domain = "messages";
$rv['putenv'] = putenv("LC_ALL=" . $locale);
$rv['setlocale'] = setlocale(LC_ALL, $locale);
$rv['bindtextdomain'] = bindtextdomain($domain, _LOCALES_DIR);
$rv['bind_textdomain_codeset'] = bind_textdomain_codeset($domain,"UTF-8");
$rv['textdomain'] = textdomain($domain);
print_r($rv);
echo "pl: " . gettext("Benutzername");
PHP Output:
Array (
[putenv] => 1
[setlocale] => Polish_Poland.1250
[bindtextdomain] => C:\Users\SM\PhpstormProjects\website\src\i18n
[bind_textdomain_codeset] => UTF-8
[textdomain] => messages
)
pl: Benutzername
Expected output: "pl: użytkownik"
The .po file looks like this:
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: POEditor.com\n"
"Project-Id-Version: website\n"
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#:
msgctxt "Usermanagement"
msgid "E-Mail"
msgstr "e-mail"
#:
msgctxt "Usermanagement"
msgid "Passwort"
msgstr "hasło"
#:
msgctxt "Usermanagement"
msgid "Benutzername"
msgstr "użytkownik"
What I tried:
The return value of the setlocale("plk") ist "Polish_Poland.1250" so I tried to rename the "i18n/plk" folder to "i18n/Polish_Poland.1250" without luck.
use Polish_Poland.1250 as input language
Polish is only an example, tried it with different languages
added ".UTF8" and ".UTF-8" to the locale
tried php-gettext
checked the installed locales with the help of this script: https://stackoverflow.com/a/23286243
But always the same result :(
Does one of you have any ideas what am I doing wrong or could trie to get it to work?
UPDATE 2016-07-15 12:45:
One of my mistakes is the missing context, I had to use gettext() like this gettext("Usermanagement\004Benutzername");. Now it loads text from the mo files, but the wrong one. It always loads the mo file located in the "i18n/de_DE" folder. (Remember de_DE is the default language of my Windows installation). Even setlocale returns the entered locale (setlocales way to tell he successfully changed the locale), always de_DE is used. :/
I also tried additionally to set these to environment variables without any luck:
$rv['putenv=LANG'] = putenv('LANG='.$locale);
$rv['putenv=LANGUAGE'] = putenv('LANGUAGE='.$locale);

Related

Unable to use gettext to retrieve the translated string in .mo files

I'm trying to setup a clean environment to test php's gettext with. I forked from one of the example and started there, but failed to get it work:
https://github.com/yookoala/gettext-example
(If needed, please clone the source code and test yourself)
The main portion of the PHP script:
<?php
// set locale to either first argument or the $_GET['locale']
$localeToSet = $argv[1] ?? $_GET['locale'] ?? 'zh_HK.utf8';
if (($locale = setlocale(LC_ALL, [
$localeToSet,
"$localeToSet.utf8",
"$localeToSet.utf-8",
"$localeToSet.UTF8",
"$localeToSet.UTF-8",
])) === false) {
throw new Exception($localeToSet . ' is not supported in this system');
}
bindtextdomain('messages', 'locale');
textdomain('messages');
printf("locale: %s - \n", $locale);
printf(_("Hello, %s, it is nice to see you today.\n"), "Vic");
The locale/zh_HK/LC_MESSAGES/messages.po file:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Codegroove.net
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL#ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr "Project-Id-Version: Codegroove.net Example Translations 0.0.1\n"
"Report-Msgid-Bugs-To: vmc#codegroove.net\n"
"POT-Creation-Date: 2010-05-28 06:18-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL#ADDRESS>\n"
"Language-Team: LANGUAGE <LL#li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#, php-format
msgid "Hello, %s, it is nice to see you today.\n"
msgstr "你好,%s,很高興今日與你會面。\n"
Both the CLI and PHP test server failed to show the translated text (as it is supposed to be). It's just showing the raw message.
Does anybody here have idea what is wrong with my setup? Or how I might trace the problem?
There is also a command-line version of gettext. Try this:
TEXTDOMAIN=messages TEXTDOMAINDIR=locale LC_ALL=zh_HK.UTF-8 gettext 'Hello, %s, it is nice to see you today.
>'
Instead of the newline, you have to hit ENTER and then add the closing quote. The > comes from your shell.
Does that work? Then you know that the problem lies in your code. And if it doesn't work, the problem is in your setup, your local environment. Try to see which directories and files are considered by gettext, for example with strace or so.
Other possible errors:
The translation is retrieved from an mo file, not a po file. Does it exist? Try msgunfmt locale/zh_HK/LC_MESSAGES/messages.mo.
Try to specify an absolute path for the locale directory with bindtextdomain('messages', '/path/to/locale');
Are you using Windows?
What locale is actually used? You didn't post the output of your script.

PHP - GetText not working

I'm trying to add translations to my webpage.
Unfortunately my translation isn't being read.
However, one translation is read (even though I ask for a different one).
My php code looks like this:
$language = "en_US"; //Hardcoded for debugging purposes
define("FOLDER_SPECIFICATION", "./locale/");
define("DOMAIN", "messages");
define("CODE_SET", "UTF-8");
putenv("LANG=" . $language);
setlocale(LC_ALL, $language);
bindtextdomain(DOMAIN, FOLDER_SPECIFICATION);
bind_textdomain_codeset(DOMAIN, CODE_SET);
textdomain(DOMAIN);
My folder structure looks like this:
root >
locale >
en_US >
LC_MESSAGES >
messages.mo
messages.po
nl_NL >
LC_MESSAGES >
messages.mo
messages.po
If I change the $language variable to en_US or nl_NL it still grabs the translation from nl_NL, if I remove the nl_NL folder it doesnt translate at all, this together means one thing: The en_US translation isn't being read.
Both messages.po contain headers and such and both are valid (I loaded them in poedit).
My question is: Why does it grab nl_NL even though I never told the code to grab it, and why isn't the other translation (en_US) being read?
Both .po files look like this (the 'Language' tag in the headers are obviously different):
msgid ""
msgstr ""
"Project-Id-Version: My Project\n"
"POT-Creation-Date: 2014-08-05 13:32+0100\n"
"PO-Revision-Date: 2016-04-19 10:43+0200\n"
"Last-Translator: \n"
"Language-Team: someone <s.omeone#something.com> \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: nl_UL\n"
"X-Poedit-SourceCharset: UTF-8\n"
msgid "Banaan"
msgstr "Banana"
msgid "Appel"
msgstr "Apple"

Gettext example not working on Windows 7 - XAMPP

I have the latest XAMPP (3.2.1) with PHP 5.6.8 and gettext enabled. I'm trying to get gettext() working there using a sample I've found on the internet: https://github.com/leftnode/gettext-example , but it is not working.
Other code I've tried (translation.php):
<?php
session_start();
$textdomain = "messages";
$lang = "de_DE";
echo(putenv("LC_ALL=".$lang)."<br>"); // outputs 1
setlocale(LC_ALL, $lang);
echo(bindtextdomain($textdomain, "locale")."<br>"); // successfully outputs the correct path to locale
textdomain($textdomain);
echo ((function_exists("_") && function_exists("gettext"))?"gettext loaded\n<br>":""); // outputs gettext loaded
$name = "Vic";
printf(_("Hello, %s, it is nice to see you today.\n"), $name); // outputs original english
?>
translation files - compiled with Poedit 1.8.1 (messages.po)
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Codegroove.net
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL#ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: Codegroove.net Example Translations 0.0.1\n"
"Report-Msgid-Bugs-To: vmc#codegroove.net\n"
"POT-Creation-Date: 2015-06-01 11:34+0100\n"
"PO-Revision-Date: 2015-06-01 11:38+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.1\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-Basepath: ..\\..\\..\\\n"
"X-Poedit-SearchPath-0: .\n"
#: translation.php:15
msgid "Hello, %s, it is nice to see you today.\n"
msgstr "Hallo, %s, es ist schön dich zu sehen heute.\n"
File locations
gettext\translation.php
gettext\locale\de_DE\LC_MESSAGES\messages.po
gettext\locale\de_DE\LC_MESSAGES\messages.mo
What else can I try to make the gettext working?
I've found out that the locale is not set correctly although PHP reports it does. There is a bug in PHP that is causing this: https://bugs.php.net/bug.php?id=66265
As a result gettext always uses system default locale for translations (after creating translations with my system locale it actually works).
Related StackOverflow question: Gettext will always use system default locale
Although the bug is closed and it should somewhat partially work I wasn't able to get it running.
Instead I'm now using PHP solution that reads gettext .po files and that works: php-gettext (https://launchpad.net/php-gettext)
I had the same problem and found the solution by setting the LANG-parameter before starting apache.
I open up a Command-Prompt (as administrator), next:
set LANG=nl_NL
xampp-control
After afull day with nothing working I have found a proper working and simple 5 line workaround which i explain in a different post:
GetText doesn't translate my text properly when using dutch

PHP Gettext not working via cli or apache

Running php-5.3.10
This is my first time setting up a website with i18n via gettext. However, the English text is still being printed, instead of the Dutch text I'm expecting. I've been Googling for two days now, but I still haven't found a solution.
The php code, even when run from cli it does not give a translation, so Apache caching is not the issue here. The code:
<?php
// no errors are thrown, sadly
error_reporting(E_ALL);
$domain = 'test';
setlocale(LC_ALL, 'nl_NL.utf8'); // returns 'nl_NL.utf8', I've also tried without '.utf8' etc.
bindtextdomain($domain, dirname(__FILE__) '/locale'); // returns correct path
bind_textdomain_codeset($domain, 'UTF-8');
textdomain($domain); // returns 'test'
// this prints the date in Dutch so setlocale works
echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));
// this should print the translated version but just prints 'Home'
echo ' ' . gettext('Home');
The Dutch locale is installed according to 'locales -a' and is listed as:
nl_AW
nl_AW.utf8
nl_BE.utf8
nl_NL.utf8
This is the .po file:
msgid ""
msgstr ""
"Language: nl\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgid "Home"
msgstr "Thuis"
And it's correctly compiled to a .mo file, msgunfmt gives no errors at least. I've tried to put this file into locale/nl/LC_MESSAGES/, locale/nl_NL/LC_MESSAGES/ and locale/nl_NL.utf8/LC_MESSAGES/. To no avail.
I'm mainly looking for a way to debug this. This whole trial and error approach is getting a bit time consuming.
I found the solution, but no clue WHY I had to do this. For both cli and apache I managed to get translations working. This is what I did.
putenv('LANGUAGE=nl_NL');
Using LANGUAGE together with LC_ALL in putenv also breaks the translation for Apache, so do not use:
putenv('LC_ALL=nl_NL');

Server ignoring my setlocale settings

I am dealing with this problem quite a while and this is not my first question to it, but still I can not get localization to work correctly.
I use WAMP server and php gettext.
A simple code I made for demonstration of my problem:
/* dirs */
$directory = realpath('../locale');
$domain = 'messages';
/* trying to find out correct setting - last one is winner */
$locale ="ro";
$locale ="ro_utf8";
$locale ="ro_RO";
$locale ="ro_RO.UTF-8";
$locale ="Romanian_Romania.1250";
putenv("LANG=".$locale);
print setlocale( LC_ALL, $locale);
setlocale( LC_ALL, $locale);
bindtextdomain($domain, $directory);
textdomain($domain);
bind_textdomain_codeset($domain, 'UTF-8');
/* STRING TO BE TRANSLATED */
echo _('string');
In ../locale directory there are many folders like this - $language_name/LC_MESSAGES/. These contain corresponding .po and . mo files with translations like this:
msgid "string"
msgstr "string SK"
in sk_SK folder
or this
msgid "string"
msgstr "string RO"
in ro, ro_RO, ro_RO.UTF8, ro_RO.UTF-8, romanian, Romanian_Romania, Romanian_Romania.1250 folders.
And what document looks like:
Romanian_Romania.1250 string SK
So you can see clearly - I setlocale() to romanian, yet my text is translated using the translation in sk_SK directory. What am I doing wrong?
Are there some functions I could use to get informations about $locale strings and directory names my server expects to find?
try to do your code like this:
setlocale(LC_ALL, 'ro_RO','Romanian');
it had worked in my project
You can help :
locale -a
And you can whach the language exist in your computer.
sudo locale-gen pt_PT
sudo locale-gen pt_PT.utf8
sudo update-locale

Categories