Почему Yii игнорирует мой файл.po?
Поскольку Yii не может создавать PO-файлы без специального расширения, я просто создал.po-файл с помощью Poedit. Я хочу использовать CGettextMessageSource
и настроил все в main.php
,
Но Yii просто игнорирует мои настройки в main.php
и сам мой.po файл.
main.php
'language' => 'de_DE',
[...]
'components' => array(
'messages' => array(
'class' => 'CGettextMessageSource',
'useMoFile' => false,
'catalog' => 'messages',
'basePath' => 'protected/messages'
),
),
мой почтовый файл
protected => messages => de_DE => messages.mo, messages.po
содержание моего.po файла
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."
Так как я не могу продлить t
-функция из-за строгих стандартов, я написал обертку в yii.php
который я скопировал в protected
и включить его в main.php
,
class Yii extends YiiBase
{
public static function _($message, $category, $params = array())
{
return parent::t($category, $message, $params);
}
}
И это мой index.php, где у меня есть строка, которая должна быть преобразована:
<?php echo Yii::_('_TEST_', 'messages');?>
3 ответа
Прежде всего, Yii не проигнорировал мой.po файл.
Проблема:
Yii просто прослушивается.
Если вы хотите использовать.po файлы для перевода, он использует класс 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;
}
Как вы можете видеть - может быть, не на первый взгляд, но позже наверняка, шаблон делает "msgctxt" необязательным. Но проблема в том, что в цикле for он проверяет, совпадает ли именно этот 'msgctxt' из файла.po с категорией, которую вы передаете t()
,
Поэтому, если у вас нет для каждой записи.po "msgctxt", это не сработает. Кроме того, вы можете видеть, что в этом классе также есть функция сохранения - но у нее нет шансов использовать ее (или я не нашел способа использовать ее). Потому что, если вы используете yiic messages
он всегда генерирует php-файл, независимо от того, настроены ли вы CGettextMessage
в настройках вашей консоли или нет.
Решение:
Поскольку я не хочу исправлять эту загрузку кода, я подумал о том, чтобы просто использовать gettext в php. Побочным эффектом является то, что я могу разобрать его намного проще с помощью таких инструментов, как Poedit.
И что самое приятное - уже есть расширение Yii, которое вы можете использовать очень просто - Yii-gettext!
Так как я действительно новичок в gettext(), я немного запутался, где разместить и как назвать мои файлы перевода. Но на ТАК я нашел этот вопрос / ответ, где они объясняют это очень хорошо. (Помимо того, что мне пришлось редактировать и этот пост. Потому что автор использовал domain
сообщения, которые немного сбивают с толку, потому что жестко закодированная часть пути к папке gettext LC_MESSAGES
, Поэтому я переименовал domain
сообщения в mycatalog.)
Помните:
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
Вам не хватает контекста "msgctxt" в вашем po-файле.
[...]
msgctxt "messages"
msgid "_TEST_"
msgstr "Congratulations! You have successfully created your Yii application."
msgctxt "messages"
msgid "_TEST2_"
msgstr "Another translated text."
[...]
Как @chris--- сказал, что вы скучаете по msgctxt. Скажите поедить сгенерировать msgctxt
от Yii:t()
category
param, установив соответствующий заголовок в вашем.po файле:
"X-Poedit-KeywordsList: t:1c,2\n"
Это означает, что первый параметр будет использоваться как context
в gettext, а второй - в виде строки сообщения.
Также см. Мою статью вики.