ZF2 翻译器在控制器中不工作?
ZF2 translator is not working in controller?
我试图通过 ServiceLocator
在控制器中进行翻译,但这不是翻译,我在 Whosebug 中尝试了很多 sulotions 但没有成功。我的系统使用多种语言,我的目标是在视图、控制器、表单和过滤器中使用转换器。我认为翻译器正在工作。任何建议和帮助将不胜感激。
在控制器中不工作:
$this->getServiceLocator()->get('translator')->translate('my text',$myLocale);
我的申请mudole.config.php:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',// 'locale' => 'dk_DK',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
我将 mudole.config.php 中的本地语言更改为另一种语言,但仍然无法翻译。
查看Helper/Forms
ZF2 附带视图助手 Zend\I18n\View\Helper\Translate
;这就是为什么您已经可以在视图中使用方法 $this->translate($text)
。
但是 所有 视图助手 class 从 Zend\I18n\View\Helper\AbstractTranslatorHelper
扩展而来的(包括所有表单视图助手)也是 'translation capable'。
您需要使用 $viewHelper->setTranslator($translator)
传递翻译器并通过 $viewHelper->setTranslatorEnabled(true)
启用翻译。
控制器插件
不幸的是,没有默认插件(我能找到)来处理控制器中的翻译器;我猜你可能会争辩说文本内容无论如何都不应该在控制器中。
您可以很容易地创建一个,如下例所示。关键是通过工厂将新的 translator
服务作为依赖项传递。
namespace MyModule\Controller\Plugin;
use Zend\Mvc\Controller\AbstractPlugin;
use Zend\I18n\Translator\Translator as TranslatorService;
class Translator extends AbstractPlugin
{
protected $translatorService;
public function __construct(TranslatorService $translatorService)
{
$this->translatorService = $translatorService;
}
public function invoke($text = null, array $options = [])
{
if (null == $text) {
return $this;
}
return $this->translate($text, $options);
}
public function translate($text, array $options = [])
{
return $this->translatorService->translate($text);
}
}
并创建工厂 class。
namespace MyModule\Controller\Plugin;
use MyModule\Controller\Plugin\Translator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
class TranslatorFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllerPluginManager)
{
$serviceManager = $controllerPluginManager->getServiceLocator();
return new Translator($serviceManager->get('translator'));
}
}
在module.config.php
中注册服务。
return [
'controller_plugins' => [
'factories' => [
'translate' => 'MyModule\Controller\Plugin\TranslateFactory',
]
],
];
然后你可以在控制器中调用它 class。
// Directly
$this->translate($text, $options);
// Or fetch the plugin first
$this->translate()->translate($text, $options);
AlexP 的回答是最好的方法。
但还有一个问题,为什么你的方法行不通?
应该可以。但这不是因为你在不同的命名空间中,所以你在文件中使用不同的域。你在做这样的事情:
namespace MyModule\Controller;
class MyController {
public function someAction() {
$this->getServiceLocator()->get('translator')->translate('my text',__NAMESPACE__,$myLocale);
}
}
在您的“module.config.php”中,您可能使用了这个命名空间:
namespace MyModule;
return array(
//...
'translator' => array(
//...
),
);
请注意,在控制器示例中 __NAMESPACE__
等于 MyModule\Controller
。在配置文件中,__NAMESPACE__
等于 MyModule
。您需要修复它,在两种情况下传递相同的值。
换句话说,有几种方法可以解决这个问题,例如 AlexP 的方法。但是,它们中的任何一个在配置时都需要具有翻译器域('text_domain'
键的值)等于调用它时 translate
方法的域参数(第二个参数)。
更快的解决方案是在控制器文件中将 $domain 参数更改为字符串:
$this->getServiceLocator()->get('translator')->translate('my text','MyModule',$myLocale);
另一个解决方案应该是创建一个常量并在文件(控制器、视图和配置)中使用它。
似乎语言环境不是直接在翻译文本中设置的,而是 $this->getServiceLocator()->get('translator')->setLocale($locale)
,现在正在翻译我的文本。
我的申请mudole.config.php:
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
在控制器中:
$this->getServiceLocator()->get('translator')->setLocale($locale);
echo $c=$this->getServiceLocator()->get('translator')->translate('Book'); // Print(Danish): Bog
您可以使用我的 ZfTranslate 控制器插件。
安装
composer require mikica/zf2-translate-plugin
您需要注册新模块。在文件 config/application.config.php 中添加:
'modules' => array(
'...',
'ZfTranslate'
),
控制器中的用法
<?php
$this->translate('translate word');
$this->translate('translate word', 'locale');
我试图通过 ServiceLocator
在控制器中进行翻译,但这不是翻译,我在 Whosebug 中尝试了很多 sulotions 但没有成功。我的系统使用多种语言,我的目标是在视图、控制器、表单和过滤器中使用转换器。我认为翻译器正在工作。任何建议和帮助将不胜感激。
在控制器中不工作:
$this->getServiceLocator()->get('translator')->translate('my text',$myLocale);
我的申请mudole.config.php:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',// 'locale' => 'dk_DK',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
我将 mudole.config.php 中的本地语言更改为另一种语言,但仍然无法翻译。
查看Helper/Forms
ZF2 附带视图助手 Zend\I18n\View\Helper\Translate
;这就是为什么您已经可以在视图中使用方法 $this->translate($text)
。
但是 所有 视图助手 class 从 Zend\I18n\View\Helper\AbstractTranslatorHelper
扩展而来的(包括所有表单视图助手)也是 'translation capable'。
您需要使用 $viewHelper->setTranslator($translator)
传递翻译器并通过 $viewHelper->setTranslatorEnabled(true)
启用翻译。
控制器插件
不幸的是,没有默认插件(我能找到)来处理控制器中的翻译器;我猜你可能会争辩说文本内容无论如何都不应该在控制器中。
您可以很容易地创建一个,如下例所示。关键是通过工厂将新的 translator
服务作为依赖项传递。
namespace MyModule\Controller\Plugin;
use Zend\Mvc\Controller\AbstractPlugin;
use Zend\I18n\Translator\Translator as TranslatorService;
class Translator extends AbstractPlugin
{
protected $translatorService;
public function __construct(TranslatorService $translatorService)
{
$this->translatorService = $translatorService;
}
public function invoke($text = null, array $options = [])
{
if (null == $text) {
return $this;
}
return $this->translate($text, $options);
}
public function translate($text, array $options = [])
{
return $this->translatorService->translate($text);
}
}
并创建工厂 class。
namespace MyModule\Controller\Plugin;
use MyModule\Controller\Plugin\Translator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
class TranslatorFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllerPluginManager)
{
$serviceManager = $controllerPluginManager->getServiceLocator();
return new Translator($serviceManager->get('translator'));
}
}
在module.config.php
中注册服务。
return [
'controller_plugins' => [
'factories' => [
'translate' => 'MyModule\Controller\Plugin\TranslateFactory',
]
],
];
然后你可以在控制器中调用它 class。
// Directly
$this->translate($text, $options);
// Or fetch the plugin first
$this->translate()->translate($text, $options);
AlexP 的回答是最好的方法。
但还有一个问题,为什么你的方法行不通?
应该可以。但这不是因为你在不同的命名空间中,所以你在文件中使用不同的域。你在做这样的事情:
namespace MyModule\Controller;
class MyController {
public function someAction() {
$this->getServiceLocator()->get('translator')->translate('my text',__NAMESPACE__,$myLocale);
}
}
在您的“module.config.php”中,您可能使用了这个命名空间:
namespace MyModule;
return array(
//...
'translator' => array(
//...
),
);
请注意,在控制器示例中 __NAMESPACE__
等于 MyModule\Controller
。在配置文件中,__NAMESPACE__
等于 MyModule
。您需要修复它,在两种情况下传递相同的值。
换句话说,有几种方法可以解决这个问题,例如 AlexP 的方法。但是,它们中的任何一个在配置时都需要具有翻译器域('text_domain'
键的值)等于调用它时 translate
方法的域参数(第二个参数)。
更快的解决方案是在控制器文件中将 $domain 参数更改为字符串:
$this->getServiceLocator()->get('translator')->translate('my text','MyModule',$myLocale);
另一个解决方案应该是创建一个常量并在文件(控制器、视图和配置)中使用它。
似乎语言环境不是直接在翻译文本中设置的,而是 $this->getServiceLocator()->get('translator')->setLocale($locale)
,现在正在翻译我的文本。
我的申请mudole.config.php:
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
在控制器中:
$this->getServiceLocator()->get('translator')->setLocale($locale);
echo $c=$this->getServiceLocator()->get('translator')->translate('Book'); // Print(Danish): Bog
您可以使用我的 ZfTranslate 控制器插件。
安装
composer require mikica/zf2-translate-plugin
您需要注册新模块。在文件 config/application.config.php 中添加:
'modules' => array(
'...',
'ZfTranslate'
),
控制器中的用法
<?php
$this->translate('translate word');
$this->translate('translate word', 'locale');