Как лучше всего использовать переключатель языка в моей системе ZF2?

Я разработал небольшую систему доктрин ZF2 для одного из моих клиентов. Пока все хорошо, но для них требуется система на 2 языках.

Я могу установить язык по умолчанию как 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 бросать 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);
}
}

0

Решение

Вам нужны средства для вызова 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');

так что это предполагает, что пользователь отправляет форму с language поле, которое содержит настройки предпочтительного языка, например 'zh_CN' или же 'en_US' как ценность.

Вы можете упростить клиентскую часть, поскольку у вас есть только два языковых варианта. Вы можете просто использовать кнопку, которая переключает язык и публикует другое значение:

Так что если в настоящее время язык 'en_US' Вы публикуете 'zh_CN' и наоборот.

2

Другие решения

После долгой битвы вот как я этого добился. Особая благодарность @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>

Надеюсь, что это поможет другим в будущем.

2

По вопросам рекламы [email protected]