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);
}
}
}
我正在使用 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);
}
}
}