CakePHP如何在同一个请求中更改__()语言

时间:2015-01-29 10:40:11

标签: php cakephp localization internationalization gettext

我在CakePHP 2.6.x上

我的应用程序已本地化为法语和英语。英语是默认的。

我的翻译文件目前如下所示:

/app/Locale/eng/LC_MESSAGES/default.po
/app/Locale/fra/LC_MESSAGES/default.po

在我的观看中,我通常可以显示当前语言的本地化文本,如下所示:

echo __("Foo");

但是,在某些情况下,我需要覆盖当前语言并返回特定语言的翻译。我的理解是__d()就是为了这个。但是,以下内容对我不起作用:

echo __d("fra", "Foo");

[更正:__d不适用于此。]

这似乎总是返回当前语言的翻译。基本上只是链接__()

经过大量的反复试验后,我重新命名了法语.PO文件......

/app/Locale/fra/LC_MESSAGES/fra.po

...然后__d("fra", "Foo"); DOES 按预期工作。但是__() 不再工作了。更改文件名后,__()的所有实例都以默认语言返回文本。

我做错了什么?如何让__d()_()同时工作?或者提出同一问题的另一种方式:如何在同一请求中更改__()使用的语言?

更新

我的第一直觉是尝试Lars在下面提出的建议。但由于某种原因,它不起作用。我在电子邮件视图中执行以下操作:

    Configure::write("Config.language", "fra");
    $this->log(Configure::read("Config.language")); //'fra'
    $this->log( __("yes") ); //'yes'

请注意,已正确设置Config语言。但是__()无视它并且无论如何回应当前的语言。 (顺便说一句,我检查过,是/ oui在PO文件中)

2 个答案:

答案 0 :(得分:3)

您最好的选择是在通话前更改设定语言并稍后再更改:

$before = Configure::read('Config.language');
Configure::write('Config.language', 'fra');
echo __('Your String');
Configure::write('Config.language', $before);

你甚至可以把它放到一个函数中:

function __lang($string, $language) {
    $before = Configure::read('Config.language');
    Configure::write('Config.language', $language);
    echo __($string);
    Configure::write('Config.language', $before);
}

修改

正如mdm在评论中解释的那样,这基本上就是I18N::translate函数的作用。

如果这(和我的功能)不起作用,我猜你的翻译文件有问题。您是否尝试过在全球范围内切换到目标语言?这会打印正确的字符串吗?

要绕过所有配置和会话值,您可以简单地依赖I18N :: translate函数:

function __lang($string, $language) {
    echo I18N::translate($string, null, null, I18n::LC_MESSAGES, null, $language);
}

答案 1 :(得分:2)

根据@ ndm的建议,我写了一个小实用程序,用于在请求中“切换”语言。

以下是我如何使用它:

App::uses('L10nTool', 'Lib');
$L10n = new L10nTool();
$L10n->startToggleLg("fra");
...
//Bonjour, mon ami
...
$L10n->stopToggleLg();//Back to initial language

稍后我可能会添加另一种方法,类似Lars的答案,用于在单个方法中执行一个快速字符串。但是现在我正在用“切换”语言做一些电子邮件逻辑,所以我这样做更容易。

以下是代码:

<?php
App::uses('AppHelper', 'View/Helper');
App::uses('CakeSession', 'Model/Datasource');

class L10nTool {

    public $start_lg;
    public $use_session = FALSE;

    public function startToggleLg($lg) {

        if (CakeSession::check("Config.language")) { 
            $this->start_lg = CakeSession::read("Config.language");
            $this->use_session = TRUE;
        } else {
            $this->start_lg = Configure::read("Config.language");
        }

        if ( $this->use_session ) {
            CakeSession::write("Config.language", $lg);
        } else {
            Configure::write("Config.language", $lg);
        }

    }

    public function stopToggleLg($lg = NULL) {

        $lg = ($lg) ? $lg : $this->start_lg;

        if ( $this->use_session ) {
            CakeSession::write("Config.language", $lg);
        } else {
            Configure::write("Config.language", $lg);
        }        

    }

}