Since Yii can not create PO files without a special extension, I just created a .po file with Poedit. I want use CGettextMessageSource and configured everything in main.php.

But Yii is just ignoring my settings in main.php and my .po file itself.

main.php

'language' => 'de_DE',
[...]    
'components' => array(
    'messages' => array(
        'class' => 'CGettextMessageSource',
        'useMoFile' => false,
        'catalog' => 'messages',
        'basePath' => 'protected/messages'
    ),
),

my po file

protected => messages => de_DE => messages.mo, messages.po

content of my .po file

msgid ""
msgstr ""
"Project-Id-Version: myTest\n"
"POT-Creation-Date: 2014-04-28 17:18+0100\n"
"PO-Revision-Date: 2014-04-29 09:16+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.6.4\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: t\n"
"X-Poedit-SearchPath-0: /..."
"trunk/fe/htdocs/protected\n"

#: /htdocs/protected/views/site/index.php:9
msgid "_TEST_"
msgstr "Congratulations! You have successfully created your Yii application."

Since I can not extend the t-function because of strict standards I wrote a wrapper in yii.php which I copied to protected and include it in main.php.

class Yii extends YiiBase
{
    public static function _($message, $category, $params = array())
    {
        return parent::t($category, $message, $params);
    }
}

And this is my index.php where I have a string that should be converted:

<?php echo Yii::_('_TEST_', 'messages');?>
有帮助吗?

解决方案 2

First of all Yii did not ignore my .po file.

Problem:

Yii is just bugged.

If you want use .po files for translation it uses class CGettextPoFile:

public function load($file,$context)
{
    $pattern='/(msgctxt\s+"(.*?(?<!\\\\))")?\s+'
        .'msgid\s+((?:".*(?<!\\\\)"\s*)+)\s+'
        .'msgstr\s+((?:".*(?<!\\\\)"\s*)+)/';
    $matches=array();
    $n=preg_match_all($pattern,file_get_contents($file),$matches);

    $messages=array();
    for($i=0; $i<$n; $i++)
    {
        if($matches[2][$i]===$context)
        {
            $id=$this->decode($matches[3][$i]);
            $message=$this->decode($matches[4][$i]);
            $messages[$id]=$message;
        }
    }
    return $messages;
}

Like you can see - maybe not on first view, but later for sure, the pattern makes 'msgctxt' optional. But the problem is, that in the for loop it checks if exactly this 'msgctxt' from .po file matches with category that you pass to t().

So if you do not have for every .po entry a 'msgctxt' it won't work. Further you can see that this class has a save function too - but there is no chance to use it (or I did not find any way to use it). Because if you use yiic messages it always generates a php file, whether you setup CGettextMessage in your console settings or not.

Solution:

Since I do not want fix this load of code, I thought about just use php's gettext. Sideeffect is, that I can parse it much easier with tools like Poedit.

And best of all is - there is already a Yii extension that you can use very easy - Yii-gettext!

Since I am really new to gettext() I was a little bit confused where to place and how to name my translation files. But on SO I have found this question/answer where they explain it very good. (Beside the fact, that I had to edit this post as well. Because the author used domain messages which was a little bit confusing, because the hard coded path part of gettext folder is LC_MESSAGES. So I renamed domain messages to mycatalog.)

Remember:

bindtextdomain(<your namespace for your .mo/.po file>, <your directory>);

//put your files into: 
//<your directory>/<language i.e. en_EN>/LC_MESSAGES/<your namespace/domain>.mo/.po
//i.e.:
//  /htdocs/locale/en_EN/LC_MESSAGES/mycatalog.mo
//  /htdocs/locale/en_EN/LC_MESSAGES/mycatalog.po

其他提示

You are missing the context "msgctxt" in your po file.

[...]
msgctxt "messages"
msgid "_TEST_"
msgstr "Congratulations! You have successfully created your Yii application."

msgctxt "messages"
msgid "_TEST2_"
msgstr "Another translated text."
[...]

As @chris--- said you miss msgctxt. Tell poedit to generate msgctxt from Yii:t() category param by setting appropriate header in your .po file:

"X-Poedit-KeywordsList: t:1c,2\n"

This means, that first parameter will be used as context in gettext, and second -- as message string.

Also see my wiki article.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top