219

Les vues et la gestion des langues

Créez site2 en copiant site1.

  1. /cms
    1. site0
    2. site1
    3. site2

Dans ce chapitre, nous allons programmer comment une URL est analysée et distribuée dans des vues différentes selon la langue demandée.

Pour tester le résultat en ligne, entrez http://www.frasq.org/cms/site2 dans la barre d'adresse de votre navigateur. Terminez l'URL par /en pour afficher la page en anglais, par /fr pour la voir en français.

Créez le dossier views dans site2, puis les dossiers fr et en dans site2/views.

  1. /cms/site2
    1. includes
    2. library
    3. views
      1. fr
      2. en

Modifiez index.php après l'appel à bootstrap :

  1. define('ROOT_DIR', dirname(__FILE__));
  2.  
  3. set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
  4. set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
  5.  
  6. require_once 'dump.php';
  7.  
  8. require_once 'bootstrap.php';
  9.  
  10. bootstrap();
  11.  
  12. require_once 'engine.php';
  13.  
  14. dispatch($supported_languages); // see config.inc

index.php appelle la fonction dispatch définie dans le fichier engine.php avec en argument la liste des langues gérées par le programme. Ajoutez le paramètre $supported_languages dans config.inc :

  1. global $supported_languages;
  2.  
  3. $supported_languages=array('fr', 'en');

La première langue définie par $supported_languages est la langue par défaut. Le code d'une langue doit correspondre à un dossier dans views.

Ajoutez les fichiers engine.php, request_uri.php et locale.php dans le dossier library avec les contenus suivants :

  1. /cms/site2
    1. library
      1. engine.php
      2. requesturi.php
      3. locale.php
  1. require_once 'requesturi.php';
  2.  
  3. define('VIEWS_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'views');

Charge le code de la fonction request_uri. Définit le dossier dans lequel les fichiers qui génèrent les vues sont regroupés.

  1. function dispatch($languages) {

dispatch détermine comment générer le document correspondant à l'URL de la requête selon les langues supportées spécifiées par $languages.

  1.     global $base_path;
  2.  
  3.     $req = $base_path ? substr(request_uri(), strlen($base_path)) : request_uri();
  4.  
  5.     $url = parse_url($req);
  6.     $path = isset($url['path']) ? trim(urldecode($url['path']), '/') : false;
  7.     $query = isset($url['query']) ? $url['query'] : false;
  8.  
  9.     if (empty($path)) {
  10.         $path = false;
  11.     }

Retire le préfixe $base_path de l'URL normalisée retournée par la fonction request_uri. Extrait le chemin d'accès et les paramètres de la requête.

  1.     /* site language */
  2.     $p = $path ? explode('/', $path) : false;
  3.     $lang = $p ? $p[0] : false;
  4.  
  5.     if ($lang && in_array($lang, $languages, true)) {
  6.         array_shift($p);
  7.         $path = implode('/', $p);
  8.     }
  9.     else {
  10.         require_once 'locale.php';
  11.  
  12.         $lang=locale();
  13.  
  14.         if (!$lang or !in_array($lang, $languages, true)) {
  15.             $lang = $languages[0];
  16.         }
  17.     }

Calcule la langue d'affichage du site. Si $path commence par une des langues contenues dans $languages, la langue est extraite de l'URL. Sinon, $lang est mis à la valeur retournée par la fonction locale si elle est supportée ou à défaut à la première langue listée dans $languages.

  1.     if (!$path)
  2.         $path='home';
  3.  
  4.     $output=view($path, $lang);
  5.    
  6.     if ($output) {
  7.         echo $output;
  8.     }
  9. }

Prend la vue appelée home par défaut. Génère le document en appelant la fonction view avec le nom de la vue et la langue en paramètres.

  1. function view($view, $lang=false) {
  2.     $file = $lang ? VIEWS_DIR.DIRECTORY_SEPARATOR.$lang.DIRECTORY_SEPARATOR.$view.'.phtml' : VIEWS_DIR.DIRECTORY_SEPARATOR.$view.'.phtml';
  3.     if (!file_exists($file)) {
  4.         header('HTTP/1.0 404 Not Found');
  5.         exit;
  6.     }
  7.     return render($file);
  8. }

view localise le fichier correspondant à $view selon la langue spécifiée par $lang. view retourne le rendu du fichier. Si aucun fichier n'est trouvé, view renvoie un document d'erreur HTTP 404 Not Found.

  1. function render($file) {
  2.     global $base_path, $base_url, $base_root;
  3.     ob_start();
  4.     require $file;
  5.     return ob_get_clean();
  6. }

render met les variables $base_path, $base_url et $base_root dans le contexte global avant de charger le fichier $file. render retourne le document généré par $file.

  1. function request_uri() {
  2.     if (isset($_SERVER['REQUEST_URI'])) {
  3.         $uri = $_SERVER['REQUEST_URI'];
  4.     }
  5.     else {
  6.         if (isset($_SERVER['argv'])) {
  7.             $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['argv'][0];
  8.         }
  9.         elseif (isset($_SERVER['QUERY_STRING'])) {
  10.             $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['QUERY_STRING'];
  11.         }
  12.         else {
  13.             $uri = $_SERVER['SCRIPT_NAME'];
  14.         }
  15.     }
  16.  
  17.     $uri = '/'. ltrim($uri, '/');
  18.  
  19.     return $uri;
  20. }

request_uri normalise le format de la requête passée dans une URL.

  1. function locale() {
  2.     if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  3.         return false;
  4.     }
  5.  
  6.     $httplanguages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  7.  
  8.     if (empty($httplanguages) === true) {
  9.         return false;
  10.     }
  11.  
  12.     $lang = false;
  13.     $quality = 0.0;
  14.  
  15.     $accepted = preg_split('/,\s*/', $httplanguages);
  16.  
  17.     foreach ($accepted as $accept) {
  18.         $match = null;
  19.         $result = preg_match('/^([a-z]{1,8}(?:[-_][a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i', $accept, $match);
  20.  
  21.         if ($result < 1) {
  22.             continue;
  23.         }
  24.  
  25.         $q = isset($match[2]) ? (float) $match[2] : 1.0;
  26.  
  27.         if ($q > $quality) {
  28.             $quality = $q;
  29.  
  30.             $lang = current(explode('_', current(explode('-', $match[1]))));
  31.  
  32.             if ($quality == 1.0) {
  33.                 break;
  34.             }
  35.         }
  36.     }
  37.  
  38.     return $lang;
  39. }

locale analyse la variable PHP $_SERVER['HTTP_ACCEPT_LANGUAGE'] pour en extraire la langue préférée de l'émetteur d'une requête HTTP.

La page d'accueil affiche une version en français et une version en anglais. Le contenu de chaque version est placé dans un fichier appelé home.phtml dans les dossiers fr et en du dossier views. Un fichier avec une extension .phtml contient du code HTML et un peu de code PHP limité à l'insertion de données calculées. Dans une vue, seule la présentation des données est prise en charge.

  1. /cms/site2
    1. views
      1. fr
        1. home.phtml
      2. en
        1. home.phtml

Commencez par rédiger la version en français :

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <title>Accueil</title>
  5. </head>
  6. <body>
  7. <h3>Bienvenue</h3>
  8. </body>
  9. </html>

Ajoutez la traduction en anglais :

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <title>Home</title>
  5. </head>
  6. <body>
  7. <h3>Welcome</h3>
  8. </body>
  9. </html>

Essayez différentes adresses comme http://localhost/cms/site2, http://localhost/cms/site2/fr, http://localhost/cms/site2/en ou http://localhost/cms/site2/fr/nullepart.

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].