Table des matières
Gestion de la langue de l'utilisateur
Dans cette page nous allons détecter automatique la langue de l'utilisateur (sfFilter et sfRequest::getPreferredCulture()) puis lui proposer de la changer (sfComponents et sfFormLanguage).
Détection automatique de la langue
On créer un filtre (sfFilter) qui va détecter la langue de l'utilisateur et la lui affecter dans l'objet user (sfUser→setCulture()). Pour que le code du filtre ne s'exécute pas à toute les requêtes, on va forcer Symfony a ne pas affecter à l'utilisateur la langue par défaut. Il faut aussi indiquer au filtre les langues disponibles sur le site.
Pas de culture par défaut
# apps/frontend/config/settings.yml all: .settings: default_culture: null
Les langues disponibles sur le site
# apps/frontend/config/app.yml all: .global: available_cultures: [fr,en]
Le filtre AutoLanguageFilter
La classe AutoLanguageFilter qui hérite de sfFilter :
# apps/frontend/lib/AutoLanguageFilter.class.php class AutoLanguageFilter extends sfFilter { public function execute( $filterChain ) { // Est-ce que la culture de l'utilisateur est nulle ? if( $this->getContext()->getUser()->getCulture() == null ) { // retrouve les cultures dispo pour le site $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { // Pas trouvées, erreurs de configuration throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } // retrouve automatique la culture préférée de l'utilisateur, parmi celles dispo sur le site. $this->getContext()->getUser()->setCulture( $this->getContext()->getRequest()->getPreferredCulture( $available_cultures ) ); //sfContext::getInstance()->getLogger()->debug( 'automatic user\'s culture selection : '.$user->getCulture() ); } // Execute next filter $filterChain->execute(); } }
et activation du filtre:
# apps/frontend/config/filters.yml ... # insert your own filters here AutoLanguageFilter: class: AutoLanguageFilter
Sélection de la langue par l'utilisateur
Création IHM de sélection
On va tout d'abord créer un composant pour gérer l'affichage (IHM) de la sélection de la langue par l'utilisateur. Ce composant hérite de sfComponent et utilise le form sfFormLanguage fourni par le plugin sfFormExtraPlugin.
# apps/frontend/modules/default/actions/components.class.php class defaultComponents extends sfComponents { public function executeChangeLanguage(sfWebRequest $request) { $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } $this->form = new sfFormLanguage( $this->getUser(), array('languages' => $available_cultures ) ); } }
Le template associé à ce composant contient le Form nécessaire à sfFormLanguage:
<!-- apps/frontend/modules/default/templates/_changeLanguage.php --> <form action="<?php echo url_for('@change_language') ?>" method="post"> <label for="language">Choose a language:</label> <?php echo $form['language'] ?> <?php echo $form->renderHiddenFields() ?> <input type="submit" value="ok"> </form>
Ce code (defaultComponents→executeChangeLanguage()) réalise par mal de traitement, via sfFormLanguage qui retrouve toutes les langues dispo dans Symfony pour en extraire celles indiquées dans la configuration du site. On va donc éviter du travail au moteur Php en activant le cache pour ce composant, de cette façon il ne sera exécuté que la 1ère fois.
# apps/frontend/modules/default/config/cache.yml _changeLanguage: enabled: true
Traitement de la sélection
Création d'une route pour l'action @change_language:
# apps/frontend/config/routing.yml change_language: url: /change_language param: { module: default, action: changeLanguage }
Et le code de l'action:
# apps/frontend/modules/default/actions/actions.class.php class defaultActions extends sfActions { ... public function executeChangeLanguage($request) { $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } $this->form = new sfFormLanguage( $this->getUser(), array('languages' => $available_cultures ) ); if ($this->form->process($request)) { // culture has been changed } return $this->redirect('@homepage'); } }
Et voilà, j'espère ne rien avoir oublié…