PHP : détecter la langue favorite de l’utilisateur

Supposons le cas d’un site multilingue, qu’il soit architecturé en sous-répertoires ou sous-domaines.
Lorsque vous arrivez sur la base du site (/ ou www), aucune langue n’est définie. Et vous n’avez aucun contenu à afficher.

Il vous faut donc rediriger l’utilisateur vers une autre page qui correspondra à la langue qu’il est le plus susceptible de désirer.
De nombreux sites, corporate y compris, ne s’embêtent pas et proposent simplement une liste de liens vers les diverses langues.

Ceci est à ne surtout pas faire. Cela avait notemment été dit par Elie Sloïm lors des ateliers Paris Web de l’an dernier (d’ailleurs les dates du prochain Paris Web ont été divulguées !)
Suite à une discussion sur le forum seosphere, je publie ici le code que j’utilise sur RefStats pour détecter la langue préférée de l’utilisateur et le rediriger vers le répertoire approprié. Si vous utilisez des sous-domaines, il suffit de déplacer /fr en fr.
Note : le code ici est adapté afin d’enleve la dépendance à CakePHP.

$langs = array('en' => array('title' => 'English', 'visible' => 0) , 'fr' => array('title' => 'Français', 'visible' => 1));
$defaultLang = ‘fr’;

$_d = split (’[,;]‘, $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$f = false;
$selected = null;
foreach($_d as $l) {
      if (isset($langs[$l]) && $langs[$l]['visible'] == 1 && $f == false) {
           $selected = $l;
           $f = true;
      }
}
if ($f == false) $selected = $defaultLang;

header(’location: /’.selected, true, 301);
die();

Quelques explications.
Ce code doit être placé sur votre page /index.php. la variable $langs contient toutes les langues disponibles. Ici, j’ai mis un élément ‘nom’ car dans le cas de RefStats, cette variable sert également à mettre le nom de la langue en haut de page.
Le ‘visible’ n’est pas non plus utile ici.

Nous regardons donc le contenu de HTTP_ACCEPT_LANGUAGE, qui contient les langues préférées de l’utilisateur, par ordre de préférence.
On prends la première que l’on connaisse. Si il n’y en a aucune, on prends la valeur de $defaultLang.
Et on redirige vers le répertoire de la langue.

Il est totalement inutile de placer la langue dans la session. En effet, vu que vous serez ensuite dans le répertoire de la langue, vous aurez toujours l’information de celle-ci.
Et si vous placez l’information en session et forcez toujours cette langue, vous courrez le risque d’avoir un utilisateur qui aurait une configuration inappropriée (cela peut arriver lors de vacances à l’étranger par exemple) qui ne pourra pas voir votre site dans sa langue maternelle.

Pour finir, voici le code non modifié pour ceux qui utiliseraient CakePHP.

Dans app_controller.php, avant la déclaration de classe :
uses('L10n');

Dans app_controller.php, en dehors de toute méthode :
var $langs = array('en' => array('title' => 'English', 'id' => 'eng', 'visible' => 0) , 'fr' => array('title' => 'Francais', 'id' => 'fre', 'visible' => 1, 'wp_cat' => 3));
var $defaultLang = ‘fr’;

Dans app_controller.php, fonction beforeFilter :
if (!isset($this->params['lang']) && !empty($this->params)) {
      $_d = split (’[,;]‘, env(’HTTP_ACCEPT_LANGUAGE’));
      $f = false;
      $selected = null;
      foreach($_d as $l) {
           if (isset($this->langs[$l]) && $this->langs[$l]['visible'] == 1 && $f == false) {
                $selected = $l;
                $f = true;
           }
      }
      if ($f == false) $selected = $this->defaultLang;

      $this->redirect(’/’.$selected, 301);
      die();
} elseif (!empty($this->params['lang']) && isset($this->langs[$this->params['lang']])) {
      Configure::write(’Config.language’, $this->langs[$this->params['lang']]['id']);
} elseif (!empty($this->params)) {
      $this->cakeError(’error404′, array(array(’action’ => $this->action)));
} else {
      $url = env(’argv’);
      $url = $url[0];
      $url = ‘/’.str_replace(’url=’, ”, $url);

      $l = explode(’/', $url);
      $l = $l[1];

      if (!isset($this->langs[$l]) && Configure::read(’debug’) == 0) {
           $this->cakeError(’error404′, array(array(’action’ => $this->action)));
      }
}
$this->params['langs'] = $this->langs;

Et enfin dans routes.php, pour permettre l’ajout du paramètre de langue avant le contrôleur et l’action :
Supprimer la ligne suivante :
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Et ajouter à la place les deux lignes suivantes :
Router::connect('/:lang/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect(’/:lang/:controller/:action/*’);

Ceci définira la langue dans la configuration de CakePHP, vous permettant par la suite d’utiliser les outils d’internationalisation du framework.

This entry was posted on Vendredi, juillet 4th, 2008 at 23:48 and is filed under Développement. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Post a Comment