We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Need help with gettext [SOLVED]

Hi there,

My directory structure is set up as explained here https://github.com/phalcon/incubator/tree/master/Library/Phalcon/Translate/Adapter, In my ControllerBase, I'have a function:

protected function _getTranslation()
  {
    return new Phalcon\Translate\Adapter\Gettext(array(
        'locale' => 'fr_FR',
        'file' => 'messages',
        'directory' => '../app/lang'
    ));
  }

messages.po and messages.mo are alvailable in app/lang/fr_FR/LC_MESSAGES

In IndexController, IndexAction:

$this->view->setVar("t", $this->_getTranslation());

And in index.volt view:

{{ t._('Hello') }}

But nothing is translated and I've got no errors... What am I doing wrong ?

########## SOLVED ###########

After double checking my code with xdebug, and being sure that everything is OK, I've inspected my gettext installation (linux debian 7): 1/ be sure that all the locales you need are activated in /etc/locale.gen 2/ generate them with locale-gen 3/ in Phalcon\Translate\Adapter\Gettext configuration array use for the locale : fr_FR.UTF8 (you have to specify the character encoding otherwise it won't work).



3.0k

Does php {{ _('Hello') }} do anything?



8.1k
  • can the Gettext adapter truly find your language files? (i.e. is your 'directory' parameter correct?)
  • remember to restart PHP (that's what I have to do on Windows at least), after you've updated your .mo file

It's a good idea to first make sure you get the desired result in your PHP code (controller) using a var_dump? (remember to have {{ content() }} in place in your volt tpl then).



43.9k

var_dump gives an object: object(Phalcon\Translate\Adapter\Gettext)[53] looks like it is empty ?



43.9k

Note that by using nativeArray or database adapter, translations are working very well, but I would really like to have gettext extension working because my "translation team" is used to use poedit.



43.9k
Accepted
answer

Solved, thanks to whose who have tried to help me.

Thanks, it solved my problem

The github link https://github.com/phalcon/incubator/tree/master/Library/Phalcon/Translate/Adapter in the OP no longer exists. Can someone point me to some instructions for how to set up the structure?



8.1k

The link works for me?

Oh! The link in the OP included the comma, which of course gives a 404 error. I copied it to my post without the comma (without noticing that the forum had picked up the comma in the link initially). Works now! Now I'll try to follow the instructions and see if it works for me.

Sorry I'm such a newbie at Phalcon, but reading the Readme on github just got me more confused. I don't understand at least two things:

  • why just calling gettext() (or _() ) doesn't work - other normal PHP works, so why does this need something special?
  • where I'm supposed to put the file I get from that github incubator - if this was any other framework (i.e. just a bunch of PHP files sitting on the server), I would know what to do, but Phalcon is compiled C inside PHP, from what I understand, so what do I do with Gettext.php and such?

In my stubs, Phalcon/Translate/Adapter/ has just one file: NativeArray.php (with public methods query() and exists()).



8.1k

You don't have to use the class, of course you can also write your own / create your own implementation. But I guess this gives everything you need. It extends the built-in abastract Phalcon\Translate\Adapter class, so it integrates nicely in the Phalcon 'eco-system'.

For installation instructions, read the Incubator README: https://github.com/phalcon/incubator

You can also manually install just the Gettext adapter if you whish (just download and put the files in place), no need to install the whole Incubator. (But using Composer you have advantages like easy integration/update/dependency-check etc.) Just remember to register the namespace within your Phalcon loader. (I got it manually installed with the 'Phalcon' namespace pointing to app/library/Phalcon)



8.1k
edited Apr '14

Btw - the class currently doesn't do bind_textdomain_codeset So you may need to specify the charset in the locale, eg: 'en_US.utf8' (or adjust the class). (This stuff / what is required to get things working properly differs between OS's btw.. And there seems to be a bug on Windows with PHP 5.5: https://bugs.php.net/bug.php?id=66265 )

Thanks for the clue - I realized that if I don't have to use the class, then I must have something set up wrong. In the process of reviewing everything I had done in order to post it here, I found a typo, and voila, my stuff started working! In case someone else comes to this thread and would like to set up gettext without the Adapter class stuff, I'll leave below the steps that I had already written for renskii's review:

  • I ran phpinfo() and made sure there is a gettext section and it says that GetText Support is enabled.
  • I structured my translation files and directory structure the way the above link's instructions say, with lang under app and then en_US.utf8 (whose .po is mostly empty) and ja_JP.utf8 (where the important stuff is in my case). I copied my stuff straight from my working application that is using straight PHP with no framework, so it was easy. I use poedit to work on my translations, so I know I'll need to add my Volt syntax to its rules list.
  • In services.php, inside $di->set('volt', function ($view, $di) use ($config) { I have this - the filter was an idea from a friend who is mentoring me while I get started with Phalcon, although he doesn't know anything about i18n per se:
    $domain = "default";
    textdomain($domain);
    bindtextdomain($domain,"/path/to/my/project/app/lang");
    bind_textdomain_codeset($domain, "utf8");

    $volt->getCompiler()->addFilter('tr', function($resolvedArgs, $exprArgs) {
        return 'gettext(' . $resolvedArgs . ')';
    });
  • I don't yet have my login code that determines the language preference of the user, but for testing, in my bootstrap file, after including services.php, I have setlocale(LC_ALL, "ja_JP.utf8"); You would have something similar, but like me, it would eventually be dynamically set in some way that fits your application. The locale name must match the name of the language directory.
  • In my Volt files, all I have to do is {{ "String"|tr }} - shorter and easier to see, I think, than what le51 is doing. If it's a variable passed from the controller, don't use the quotes: {{ variable|tr }} (but if you pass in a string that isn't literal somewhere else, poedit won't find it, so you'd have to handle it manually, which would a pain - just a warning).

This works with nothing additional installed.

Oh, I see that you wrote something else while I was doing my thing. But yes, I have always included the charset in the locale, even before Phalcon.

You mentioned OS - my development server for Phalcon is CentOS 6.4, and I'm running nginx with PHP 5.59, if that matters. I suspect the main difference between different Linux distros would be the path to the project, but I could be wrong. The production server I copied stuff from is CentOS 5.6, so I'm unaware of how things might work on totally different OS's. I would never even think of attempting this stuff on Windows! ;-)

This answer should be part of the documentation ;)

I tried the solution proposed in this post, but seems it doesn't works for me. With php version 5.6.17 and phalcon version 2.0.9 I created the folders like you said (path/to/modules/moduleName/Language/it_IT/LC_MESSAGES/ and messages.po and .mo inside)

In my BaseController I have the method _getTranslation() with the following content:

$translator =  new \Phalcon\Translate\Adapter\Gettext(array(
'locale' => 'it_IT.utf8',
'file' => 'messages',
'directory' => __DIR__ . '../Language/'
));
return $translator;

Then the IndexController extends that with:

$this->view->setVar("translator", $this->_getTranslation());

And finally i call it in volt:

{{translator._("Hello world")}}

As I said it doesn't work, and I get no errors either... Can anybody give some suggestions or help?



43.9k

Hi,

as I said in first post, double check your locales on your server. Here on debian7:

1/ be sure that all the locales you need are activated in /etc/locale.gen

2/ generate them with locale-gen

3/ in Phalcon\Translate\Adapter\Gettext configuration array use for the locale : fr_FR.UTF8 (you have to specify the character encoding otherwise it won't work).

The problem seems to be that I don't have the 'locale.gen' file.

The command locale-gen seems to work, but the file in /etc doesn't exists, so I guess there must be something wrong.

(I have ubuntu 14.04) Do I have to create that file? And if I have to, is there a command to do that (except for locale-gen)? What is exactly the content it must have?

Thank you for your help



2.3k

Do you found a way to extract string from .volt files ? With poedit or this one https://www.icanlocalize.com/tools/php_scanner don't work.. thanks

You need to do the following before adding your translator:

        setlocale(LC_ALL, "fr_FR");
        putenv("LC_ALL=fr_FR");

Remember to add the category => LC_MESSAGES to your gettext array, and place gettext files under DIR . '../Language/it_IT.utf8/messages.mo



2.3k

Thanks for your reply. But this is not what I have asked.

As I know, using phalcon you don't need to setlocale or putenv, this is already done with phalcon gettext adapter, when you create new instance, for example:

    $gettext = new \Phalcon\Translate\Adapter\Gettext([
        'locale' => 'en_US',
        'defaultDomain' => 'default',
        'directory' =>  '/var/my/locale/' 
    ]);

As you can see here phalcon setup already for you the locale: https://github.com/phalcon/cphalcon/blob/master/phalcon/translate/adapter/gettext.zep#L201

I have already setup gettext on my installation and work fine.

What I need is to extract phrase from view files into .po file..

You need to do the following before adding your translator:

       setlocale(LC_ALL, "fr_FR");
       putenv("LC_ALL=fr_FR");

Remember to add the category => LC_MESSAGES to your gettext array, and place gettext files under DIR . '../Language/it_IT.utf8/messages.mo

You were right, I've tried and it works :-)

I've fight against .volt files and poEdit, finally I had to do what I say in my last message here:

https://forum.phalcon.io/discussion/9683/volt-gettext-parser-is-now-available-through-xgettexttemplate#C34287

Maybe it could helps you :-)

edited May '16

Have you tried to run poedit against the compiled template files ? see parameter compiledPath in https://docs.phalcon.io/en/latest/reference/volt.html#setting-up-the-volt-engine



2.3k

Yes, using cache view files is the only solution at the moment. but I prefer to use volt file.

Have you tried to run poedit against the compiled template files ? see parameter compiledPath in https://docs.phalcon.io/en/latest/reference/volt.html#setting-up-the-volt-engine

Still don't know how it works, same problem here.

Solved, thanks to whose who have tried to help me.