Я разработал небольшую систему доктрин ZF2 для одного из моих клиентов. Пока все хорошо, но они требуют системы на двух языках.
Я могу установить язык по умолчанию как english
или another language
из моего module/Application/config/module.config.php
'translator' => array( 'locale' => 'en_US', 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo', ), ), ),
И я также могу использовать этот метод для установки значения по умолчанию в module.php
public function onBootstrap(MvcEvent $e) { $application = $e->getApplication(); $serviceManager = $application->getServiceManager(); // Just a call to the translator, nothing special! $serviceManager->get('translator'); $this->initTranslator($e); // Etc, more of your bootstrap function. } protected function initTranslator(MvcEvent $event) { $serviceManager = $event->getApplication()->getServiceManager(); // Zend\Session\Container $session = New Container('language'); $translator = $serviceManager->get('translator'); $translator ->setLocale($session->language) ->setFallbackLocale('zh_CN') ; }
Это хорошо, теперь моя система показывает язык по умолчанию как китайский. Тем не менее, я хотел бы дать возможность пользователям выбирать.
Как мне это сделать?
Я нашел эту ссылку, но я не мог заставить ее работать.
Когда я добавляю следующую функцию в Application/IndexController.php
она ничего не делает вместо http://myurl.com/changeLocal
throw 404 error
. Нужно ли добавлять что-либо в module.config.php
?
public function changeLocaleAction() { // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); $language = $request->getPost()->language; $config = $this->serviceLocator->get('config'); if (isset($config['locale']['available'][$language])) { $session->language = $language; $this->serviceLocator->get('translator')->setLocale($session->language); } }
Вам нужны средства для вызова changeLocaleAction
. Маршрут, связанный с этим действием контроллера, действительно будет самым простым:
'language' => array( 'type' => 'literal', 'options' => array( 'route' => '/language', 'defaults' => array( 'controller' => `Application\Controller\IndexController`, 'action' => 'changeLocaleAction' ) ) ),
Вам нужно поймать значение post для языка в вашем методе:
$request->getPost('language');
Или в вашем контролере, используя плагин params:
$this->params()->fromPost('language');
поэтому это указывает на то, что пользователь 'zh_CN'
форму с language
полем, которое содержит предпочтительный языковой параметр, например, 'zh_CN'
или 'en_US'
в качестве значения.
Вы можете упростить клиентскую сторону, поскольку у вас есть только два варианта языка. Вы можете просто использовать кнопку, которая переключает язык и публикует другое значение:
Поэтому, если в настоящее время язык является 'en_US'
вы 'zh_CN'
и наоборот.
После долгой битвы, вот как я это достиг. Особая благодарность @Kwido и @Wilt за отправку меня в правильном направлении (я проголосовал за них обоих).
Применение / Config / module.config.php
return array( 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController' ), ), 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), ), 'language' => array( 'type' => 'Segment', 'options' => array( //'route' => '/[:language]', 'route' => '/en', 'constraints' => array( 'language' => 'en', ), 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'changeLocaleEnglish' ) ) ), 'languageChinese' => array( 'type' => 'Segment', 'options' => array( //'route' => '/[:language]', 'route' => '/cn', 'constraints' => array( 'language' => 'cn', ), 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'changeLocaleChinese' ) ) ), //// // other stuff //////////// like child routes etc ), ), 'service_manager' => array( 'abstract_factories' => array( 'Zend\Cache\Service\StorageCacheAbstractServiceFactory', 'Zend\Log\LoggerAbstractServiceFactory', ), 'factories' => array( 'translator' => 'Zend\Mvc\Service\TranslatorServiceFactory', ), ), 'translator' => array( 'locale' => 'zh_CN', //default is english which is set in module.php 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo', ), ), ), 'view_helpers' => array( 'invokables'=> array( 'PaginationHelper' => 'Application\View\Helper\PaginationHelper' ) ), 'view_manager' => array( //....... view stuff ), // Placeholder for console routes 'console' => array( 'router' => array( 'routes' => array( ), ), ), );
Применение / module.php
public function onBootstrap(MvcEvent $e) { $application = $e->getApplication(); $serviceManager = $application->getServiceManager(); // Just a call to the translator, nothing special! $serviceManager->get('translator'); $this->initTranslator($e); } protected function initTranslator(MvcEvent $event) { $serviceManager = $event->getApplication()->getServiceManager(); // use Zend\Session\Container add this to top $session = New Container('language'); $translator = $serviceManager->get('translator'); if($session['language'] != 'zh_CN'){ //if session doesn't have zh_CN then set it as english $translator ->setLocale($session->language) ->setFallbackLocale('en_US') ; } }
теперь в приложении / src / Application / Controller / IndexController.php Я добавил два действия, чтобы поймать сессию и установить язык:
public function changeLocaleChineseAction() { $result = new ViewModel(); $result->setTerminal(true); $response = $this->getResponse(); // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); $request = $this->getRequest(); $config = $this->serviceLocator->get('config'); $language = $config['translator']['locale']; //default locale from Application/config/module.config.php if (isset($config['translator']['locale'])) { $session->language = $language; $this->serviceLocator->get('translator')->setLocale('zh_CN') ->setFallbackLocale('zh_CN') ; } return $this->redirect()->toRoute('home'); } public function changeLocaleEnglishAction() { // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); //just clear the language session $session->getManager()->getStorage()->clear('language'); $language = 'en_US'; //set new language $request = $this->getRequest(); $config = $this->serviceLocator->get('config'); $session->language = $language; $this->serviceLocator->get('translator')->setLocale('en_US') ->setFallbackLocale('en_US') ; return $this->redirect()->toRoute('home'); }
Теперь просто добавьте ссылку в layout.phtml
чтобы переключиться на язык:
<a href="<?php echo $this->url('home')."cn";?>"><?php echo $this->translate("Chinese");?></a> <a href="<?php echo $this->url('home')."en";?>"><?php echo $this->translate("English");?></a>
Надеюсь, это поможет другим в будущем.