ZF2, traduction en session

Petite explication sur la méthode toute simple de gérer la traduction sous Zend Framework 2.

Pour beaucoup de mes projets, je dois utiliser une gestion de langue et souvent pour les utilisateurs, un changement de langue sans perdre l’url de la page en cours. J’ai donc « pondu » ces petites lignes de code pour vous aider aussi:

  1. un nouveau controller
  2. une vue attaché à une action
  3. un nouveau helper
  4. configuration
  5. layout ou utilisation

Un nouveau controller !

On ajoute un nouveau contrôleur nommé TranslatorController.php
Il sera placé dans le dossier

module/Application/src/Application/Controller


<?php
/**
 *
 * @author Remi THOMAS
 */

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;

class TranslatorController extends AbstractActionController
{

 /**
 *
 * @return \Zend\View\Model\ViewModel
 */
 public function changelocaleAction(){

 // disable layout
 $result = new ViewModel();
 $result->setTerminal(true);

 // variables
 $event = $this->getEvent();
 $matches = $event->getRouteMatch();
 $myLocale = $matches->getParam('locale');
 $redirect = $matches->getParam('redirecturl', '');

 // translate
 $sessionContainer = new Container('locale');

 switch ($myLocale){
 case 'fr_FR':
 break;
 case 'en_US':
 break;
 default :
 $myLocale = 'en_US';
 }

 $sessionContainer->offsetSet('mylocale', $myLocale);

 // redirect
 switch ($redirect){
 case '':
 $this->redirect()->toRoute('home');
 break;
 default :
 $this->redirect()->toUrl(urldecode($redirect));
 }

 return $result;
 }
}

Une vue en relation

Créer ensuite une vue en relation avec l’action définie dans le nouveau contrôleur: changelocale.phtml

Elle sera dans le dossier module/Application/view/application/translator/

Pas besoin de contenu, le fichier est donc vide.

Un « helper » de vue

La suite est toute simple, ajouter un nouveau view helper. Pour cela je me suis basé sur l’article d’Evan Coury

Et maintenant au tour de Module.php

N’oubliez pas d’ajouter ceci à Module.php

use Zend\Session\Container;

On modifie ensuite le onBootstrap

public function onBootstrap(MvcEvent $e)
 {
 // container de session
 $sessionContainer = new Container('locale');

 // teste si la langue en session existe
 if(!$sessionContainer->offsetExists('mylocale')){
 // n'existe pas donc on ajoute la langue du navigateur
 $sessionContainer->offsetSet('mylocale', \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']));
 }

 // mise en place du service de traduction
 $translator = $e->getApplication()->getServiceManager()->get('translator');
 $translator ->setLocale($sessionContainer->mylocale)
 ->setFallbackLocale('en_US');

 $eventManager = $e->getApplication()->getEventManager();
 $moduleRouteListener = new ModuleRouteListener();
 $moduleRouteListener->attach($eventManager);
 }

module.config.php

Modifions maintenant dans module/Application/config/ le fichier module.config.php 

Il me semble que vous avez déjà une structure de tableau similaire avec les controllers

'controllers' => array(

'invokables' => array(
 'Application\Controller\Index' => 'Application\Controller\IndexController',
 'Application\Controller\Translator' => 'Application\Controller\TranslatorController'
 ),
 ),

On ajoute aussi une nouvelle route

'changelocale' => array(

'type' => 'segment',
 'options' => array(
 'route' => '/changelocale[/:locale[/:redirecturl]]',
 'defaults' => array(
 'controller' => 'Application\Controller\Translator',
 'action' => 'changelocale',
 'locale' => '',
 'redirecturl' => ''
 )
 ),
 ),

Notre layout ou l’utilisation du système

Alors je dis layout car j’ai placé dans mon footer mes changements de langue.

<ul>

<li><a href='<?php echo $this->url('changelocale', array('locale'=>'fr_FR', 'redirecturl'=>urlencode($this->absoluteUrl()))); ?>'>Français</a></li>
 <li><a href='<?php echo $this->url('changelocale', array('locale'=>'en_US', 'redirecturl'=>urlencode($this->absoluteUrl()))); ?>'>English</a></li>
 </ul>

Réponses aux commentaires

Bonne question de @emf (je ne sais pas son vrai nom ^^):

Comment fais-tu pour appeler la variable de session mylocale à partir d’une View ou d’un Layout ?

il faut rajouter ceci à Module.php

$events->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function(MvcEvent $e) use ($mylocale) {
$controller      = $e->getTarget();
$controller->layout()->mylocale = $mylocale;
}, 100);

et pourra donc appeler dans notre View la locale

$this->mylocale;

Fin !

Bon je ne peux pas terminer sans parler des problèmes rencontrés, le premier venait simplement lors de l’installation de AbsoluteUrl d’Evan Coury ; en fait mon php n’avait pas de librairie concernant Locale, ceci a été corrigé très rapidement avec ça !

# apt-get update

# apt-get upgrade

# apt-get install php5-intl
Commentaires

4 réflexions sur “ZF2, traduction en session

  1. Sympa ton code pour la traduction !
    Comment fais-tu pour appeler la variable de session mylocale à partir d’une View ou d’un Layout ?

    Merci

  2. Sympa ton tuto, merci beaucoup, par contre pour la partie Module.php avec Locale dans le cas des namespaces si on copie colle exactement ce que tu met on aura la classe Locale not found.
    Bien penser donc a mettre
    \Locale::acceptFromHttp($_SERVER[‘HTTP_ACCEPT_LANGUAGE’]

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Time limit is exhausted. Please reload CAPTCHA.