2016-01-26 5 views
0

J'ai développé un petit système de doctrine ZF2 pour un de mes clients. Tout est bon jusqu'à présent, mais ils nécessitent le système en 2 langues.Quelle est la meilleure option pour avoir un commutateur de langue dans mon système ZF2?

Je peux définir la langue par défaut comme english ou another language de mon 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', 
     ), 
    ), 
), 

Et je peux aussi utiliser cette méthode pour définir par défaut dans 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') 
     ; 


} 

Ce qui est bon, maintenant mes spectacles système langue par défaut comme le chinois. Cependant, je voudrais donner l'option aux utilisateurs de choisir.

Comment puis-je faire cela?

J'avais trouvé ceci link mais je ne pouvais pas le faire fonctionner.

Lorsque j'ajouter la fonction suivante dans Application/IndexController.php il ne fait rien à la place http://myurl.com/changeLocal jeter 404 error. Ai-je besoin d'ajouter quelque chose dans module.config.php aussi?

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

Répondre

2

Après une longue bataille, voici comment je l'ai atteint cet objectif. Un merci spécial à @Kwido et @Wilt pour me envoyer à la direction droite (j'ai voté les deux vers le haut).

Application/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(
      ), 
     ), 
    ), 
); 

Application/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') 
     ; 
    } 
} 

maintenant Application/src/Application/contrôleur/IndexController.php J'ai ajouté deux mesures pour prendre la session et la langue:

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'); 

    } 

Maintenant, il suffit d'ajouter le lien dans layout.phtml avoir switcher la langue:

<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> 

Hope this helps autres à l'avenir.

+0

Cela m'a beaucoup aidé, merci mon ami de partager! –

+0

Cheers. Bonne aide. –

2

Vous avez besoin des moyens pour appeler les changeLocaleAction. Un itinéraire qui est connecté à cette action du contrôleur serait en effet le plus facile:

'language' => array(
    'type' => 'literal', 
    'options' => array(
     'route' => '/language', 
     'defaults' => array(
      'controller' => `Application\Controller\IndexController`, 
      'action' => 'changeLocaleAction' 
     ) 
    ) 
), 

Vous devez prendre la valeur de poste pour la langue dans votre méthode:

$request->getPost('language'); 

Ou dans votre controllor en utilisant le plugin params :

$this->params()->fromPost('language'); 

donc cela suggère que les messages de l'utilisateur un formulaire avec un champ language qui détient le paramètre de langue préférée par exemple 'zh_CN' ou 'en_US' en tant que valeur.

Vous pouvez simplifier le côté client puisque vous avez deux options de langue. Vous pouvez simplement utiliser un bouton qui change de langue et affiche l'autre valeur:

Donc, si actuellement la langue est 'en_US', vous postez 'zh_CN' et l'inverse.

+0

'$ request-> getPost() -> language' cela retourne' NULL'. –

+0

Et je suis heureux d'afficher ou de voir les données en chinois ou en anglais, quelles que soient les entrées de l'utilisateur. Ma seule préoccupation est d'avoir un sélecteur de langue où mon '$ this-> translate ('Mon nom')' est traduit en conséquence avec la langue choisie par l'utilisateur. –

+0

@AdarshKhatri Eh bien, vous pourriez par exemple faire un assistant de vue de langue pour cela ... Avez-vous poster un champ appelé 'language' de votre client? Essayez '$ this-> getRequest() -> getPost ('language');' – Wilt