Gettext

Коментарии

To get this working properly on debian, install the locales-all package.  I just spent a few hours finding a bug where it wouldn't work because that package is missing
2008-08-20 22:58:38
http://php5.kiev.ua/manual/ru/book.gettext.html
My PHP app was made for UTF-8 but i had a problem that gettext always returned all texts in ISO-8859-2 instead of UTF-8.

Then i found out that you have to set locale in PHP exactly to encoding you request. So when i wanted czech UTF-8 i used:

setlocale(LC_ALL, "cs_CZ.UTF-8");

Now it works...
2009-03-19 11:16:13
http://php5.kiev.ua/manual/ru/book.gettext.html
And what about pgettext and npgettext? They are there in the gettext documentation, but there aren't in PHP. They're very useful if you have the same messages for translation, but in different contexts, so they should be translated separately and probably differently.

Fortunately, there is a simple work-around, which may help:
From the gettext.h header one can find out that pgettext() is only a macro calling dcgettext() internally with properly mangled parameters - msgctxt and msgid are glued together with use of ASCII char 4 [EOT, End Of Text]. The same way they're written in .mo files, so it's possible to refer them this way.

Here's my "emulated" pgettext() function:

<?php
   
if (!function_exists('pgettext')) {
     
      function 
pgettext($context$msgid)
      {
         
$contextString "{$context}\004{$msgid}";
         
$translation dcgettext('messages'contextString,LC_MESSAGES);
         if (
$translation == $contextString)  return $msgid;
         else  return 
$translation;
      }
     
   }
?>

By default, xgettext doesn't support pgettext function for PHP source files. But there is a parameter which can work-around it. Here's how I call xgettext:

   xgettext --force-po --keyword="pgettext:1c,2" -c -o messages.po sourceFile.php

In sourceFile.php I use the following test code:

   pgettext('menu', 'Open');  //Substitute "Otwórz"
   pgettext('forum', 'Open');  //Substitute "Otwarty", different context

Generated .po file fragment:

   msgctxt "menu"
   msgid "Open"
   msgstr "Otwórz"
   
   msgctxt "forum"
   msgctxt "Open"
   msgstr "Otwarty"

I've tested it out and everything works fine :-) If anyone have some further suggestions or fixes, please write ;-)
2009-03-31 13:18:20
http://php5.kiev.ua/manual/ru/book.gettext.html
Warning for Linux (Ubuntu) users!  Your system will *only* support the locales installed on your OS, in the *exact* format given by your OS.  (See also the PHP setlocale man page.)  To get a list of them, enter locale -a, which will give you something like this:

C
en_US.utf8
ja_JP.utf8
POSIX

So this machine only has English and Japanese!  To add eg. Finnish, install the package:

sudo apt-get install language-pack-fi-base

Rerun locale -a, and "fi_FI.utf8" should appear.  Make sure you're using the same name in your PHP code:

setlocale(LC_ALL, "fi_FI.utf8");

Adjust your po paths so that they match, e.g. "./locale/fi_FI.utf8/LC_MESSAGES/messages.po".

Now restart Apache, and it should finally work.  Figuring this out took quite a while...
2009-05-29 03:05:38
http://php5.kiev.ua/manual/ru/book.gettext.html
*An important thing to keep in mind*:
Do not forget to set the charset in .po file! 
For example:

"Content-Type: text/plain; charset=UTF-8\n"

Then PHP will be able to find the .mo file you generated, using msgfmt, from the .po file WITH CHARSET SET.

Because of this I've wasted a lot of time debugging my code, testing every single little changes people suggested over this manual and Internet: 

<?php

//this:
setlocaleLC_MESSAGES'pt_BR')
//or this:
setlocaleLC_MESSAGES'pt_BR.utf8')
//or this:
setlocaleLC_MESSAGES'')

//this:
putenv("LANG=pt_BR.utf8");
//or this:
putenv("LANGUAGE=pt_BR.utf8");

//this:
bindtextdomain('mydomain'dirname(__FILE__).'/locale');
//or this:
bindtextdomain("*"dirname(__FILE__).'/locale');
//or this:
bindtextdomain('*'dirname(__FILE__).'/locale');

//setting or not "bind_textdomain_codeset()":
bind_textdomain_codeset("mydomain"'UTF-8');
?>

As well as what locale directory name to set:
./locale/pt_BR.UTF8/LC_MESSAGES/mydomain.mo
or
./locale/pt_BR/LC_MESSAGES/mydomain.mo
or
./locale/pt/LC_MESSAGES/mydomain.mo

Finally, the code which brought the right translated strings (also with the correct charset) was:

<?php

$directory 
dirname(__FILE__).'/locale';
$domain 'mydomain';
$locale ="pt_BR.utf8";

//putenv("LANG=".$locale); //not needed for my tests, but people say it's useful for windows

setlocaleLC_MESSAGES$locale);
bindtextdomain($domain$directory);
textdomain($domain);
bind_textdomain_codeset($domain'UTF-8');
?>

And the three directory's names worked out, using the pt_BR.utf8 locale. (My tests were made restarting Apache then trying each directory).

I hope to help someone else not to waste as much time as I've wasted... =P

Using:
Ubuntu 8.04 (hardy)
Apache 2.2.8
PHP 5.2.4-2ubuntu5.6
2009-06-21 14:30:07
http://php5.kiev.ua/manual/ru/book.gettext.html
Автор:
Please also be noticed that the server will cache the .mo file on first loading and then "seldom" reload it, so your update to .mo file will not be revealed.  Some solution to clear the cache from web is to restart the apache server, or to use another name for the textdomain everytime.  These are tedious.  I cannot find better solution yet.
2014-07-14 12:31:38
http://php5.kiev.ua/manual/ru/book.gettext.html
Автор:
for all they try to use a non-alpha-char in a domain name: DONT TRY THIS !!! we have search some hours to realized that "foo-bar" is not a good idea for a domain name. sometimes we got a correct translation, and sometimes not. so just use only the characters A-Z for a domain name!
2014-12-16 14:00:13
http://php5.kiev.ua/manual/ru/book.gettext.html
Soo.... It was pretty hard)
Finaly:
1)Working if dir is "en", not "en_GB" or "en_GB.utf8". Only "en".
2)But use setlocale(LC_MESSAGES, "en_GB.utf8");
2017-10-29 12:35:07
http://php5.kiev.ua/manual/ru/book.gettext.html
How to use gettext on Windows.

If you use Linux start from the step 2 and consider cmd as linux shell.

1] First you have to download and install this 
      https://mlocati.github.io/articles/gettext-iconv-windows.html
   
    Check all options during the installation and go on.   
 

2] Create a index.php file into your website directory with this code inside:
 
   <?php 
   
echo  _("Good Morning");
   
?>

3] Open cmd and move into your website folder using cd

4] Now create the .mo files directly from the php files using this command
    xgettext -n index.php
   
    Use xgettext -help to see how to include more php files.

5] Once finished will be generate a file called messages.mo. Now you have to set the language and the charset. Open messages.mo with notepad and edit the lines:

 - "Language: \n" BECOMES "Language fr\n"
 - "Content-Type: text/plain; charset=CHARSET\n" BECOMES "Content-Type: text/plain; charset=UTF-8\n"

6] Remember to translate every line where is present msgstr "", translating the instance msgid into language you have chosen. For instance:

   #: index.php:2
  msgid "Good Morning"
  msgstr "Bonjour"

7] Once finished open cmd and move into your website folder using cd and then type
     msgfmt messages.po

 This will make a file called messages.mo . Is a binary version of the messages.po file

8] Now you have to create a folder structure like this into your website folder. Do this for each language you want to add.
   
  website/locale/fr_FR/LC_MESSAGES

9] Move messages.mo and messages.po in locale/fr_FR/LC_MESSAGES 
               
10] Now edit the index.php as follows
                                       
 <?php

 $locale 
"fr_FR";

    if (
defined('LC_MESSAGES')) {
       
setlocale(LC_MESSAGES$locale); // Linux
       
bindtextdomain("messages""./locale");
    } else {
       
putenv("LC_ALL={$locale}"); // windows
       
bindtextdomain("messages"".\locale");
    }

   
   
textdomain("messages");

    echo 
_("Good Morning");
?>

11] Open index.php in your browser and if you will see "Bonjour" it means everything is okay. If not,  start from the step 2 again.

If it was usefull for you vote up!

Visit my github profile https://github.com/TheoRelativity/
2018-03-14 11:54:59
http://php5.kiev.ua/manual/ru/book.gettext.html
I have some problems setting geettext.
I ahve tried all the above example in noted, but none work.
However, i found a nice trick here and it work!!:
My platform is freebsd.

below is the post:
function.gettext

Gettext translations are cached. If you change *.mo files your page may not be translated as expected. Here's simple workaround which does not require restarting webserver (I know, this is just a dirty hack):

<?php
function initialize_i18n($locale) {
   
putenv('LANG='.$locale);
   
setlocale(LC_ALL,"");
   
setlocale(LC_MESSAGES,$locale);
   
setlocale(LC_CTYPE,$locale);
   
$domains glob($locales_root.'/'.$locale.'/LC_MESSAGES/messages-*.mo');
   
$current basename($domains[0],'.mo');
   
$timestamp preg_replace('{messages-}i','',$current);
   
bindtextdomain($current,$locales_root);
   
textdomain($current);
    }
?>

to make this work you have to put your locale inside file messages-[unix_time].mo and use this name (without .mo) as your domain to fool caching mechanism (domain names differ)

msgfmt messages.po -o messages-`date +%s`.mo

for me this works fine (although this is not very elegant solution)
2018-08-01 11:00:04
http://php5.kiev.ua/manual/ru/book.gettext.html
<?php

// read directly .po files

function T_($contenido) {

    global 
$language;

    if (
$language == "en") { $translation_file "langs/en.po"; }
    if (
$language == "es") { $translation_file "langs/es.po"; }

    if (
file_exists("$translation_file")) {
       
$IDIOMA_CONTENT file("$translation_file");
       
$num_lineas count($IDIOMA_CONTENT);
    } else {
        return 
$contenido;
    }

    for (
$i 0$i <= $num_lineas$i++) {
       
$linea1 $IDIOMA_CONTENT[$i];
       
$linea1 rtrim($linea1);
       
$string6 substr($linea106);

        if (
$string6 == "msgid ") {
           
$orig str_replace($string6""$linea1);
           
$orig str_replace("\""""$orig);
           
            if (
"$orig== "$contenido") {
               
$linea2 $IDIOMA_CONTENT[$i 1];
               
$linea2 rtrim($linea2);
               
$string7 substr($linea207);

                if (
$string7 == "msgstr ") {
                   
$trad str_replace($string7""$linea2);
                   
$trad str_replace("\""""$trad);
                    return(
"$trad");
                }
            } else {
               
$i $i 3;
            }
        }
    }

    return(
"$contenido");
}

$language "es";

print 
T_("I on puc comprar el meu domini ?");
print 
T_("Aquí tens alguns links...");

?>
2020-10-29 19:27:21
http://php5.kiev.ua/manual/ru/book.gettext.html

    Поддержать сайт на родительском проекте КГБ