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

CakePHP how to change __() language in the same request

我正在使用 CakePHP 2。6.x

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

我的翻译文件目前是这样的:

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

在我看来,我通常可以像这样显示当前语言的本地化文本:

echo __("Foo");

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

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

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

这似乎总是return当前语言的翻译。基本上只是 link __()

经过反复试验,我重命名了法语 .PO 文件...

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

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

我做错了什么?如何让 __d()_() 同时工作?或者以另一种方式提出相同的问题:How can I change the language used by __() within the same request?

更新

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

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

请注意配置语言设置正确。但是 __() 会忽略它并以任何方式回应当前语言。 (顺便说一句,我检查过 yes/oui 在 PO 文件中)

最好的办法是在通话前更改设置的语言,稍后再改回来:

$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);
}

根据@ndm 的建议,我为 "toggling" 语言中间请求编写了一个小实用程序。

以下是我的使用方法:

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

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

代码如下:

<?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);
        }        

    }

}