Un style switcher en PHP

Mis à jour le mardi 29 octobre 2013

Un style switcher, aussi appelé sélecteur de style, est un outil permettant de switcher (donc, de changer) entre plusieurs feuilles de style, c'est-à-dire entre la feuille de style favorite et les feuilles de style alternatives.

Si vous ne connaissez pas le principe de styles alternatifs, je vous recommande la lecture de ce très bon article d'Openweb.

Réalisation du style switcher

Disposer d'un style switcher intégré à votre site vous sera indispensable dans les cas suivants :

  • le navigateur n'implémente pas cette fonction. C'est en général le cas pour les navigateurs anciens, tels qu'IE ;

  • le navigateur n'a implémenté cette fonction que partiellement. Autrement dit, votre choix ne sera pas permanent. Tous les navigateurs actuels sont dans ce cas, hormis Firefox avec l'extension Stylesheet Chooser Plus.

Autrement dit, l'utilisation des feuilles de style alternatives perdra pratiquement tout son intérêt.

Il existe actuellement deux moyens d'intégrer un style switcher à un site web : en utilisant la technologie PHP ou JavaScript.

L'idéal serait de cumuler les deux systèmes (avantages du JavaScript et accessibilité maximale).
Néanmoins, l'intégration d'un style switcher en JavaScript est loin d'être facile, et je n'ai pas les compétences requises pour réaliser cela.
Je vous redirige donc vers cet article de A List Apart Magazine.

Nous verrons donc comment en réaliser un sélecteur de style en PHP.
Tout d'abord, ce que devra effectuer notre script.

  1. À l'affichage des pages :

  • lister les différents styles et déterminer le style favori ;

  • linker les feuilles de style ;

  • afficher le formulaire de changement de style.

  • Si changement de style favori :

    • envoyer un cookie.

    Précision importante : il faut penser à changer la feuille de style favorite sans oublier de mettre les autres en alternatives.
    Il serait dommage de priver vos visiteurs de se servir du style switcher intégré à leur navigateur...

    Déjà un problème se pose : celui de choisir le titre de vos feuilles de style.
    Par exemple, si votre feuille de style se trouve dans /style/printemps/screen.css, vous voudrez peut-être afficher "Lumière de printemps" dans le formulaire permettant de changer de style.

    Il existe deux principales manières de résoudre ce problème.

    • Utiliser un array

      Array associatif défini avec le nom du dossier en key et le titre du style en value.
      Donc, de la forme array('printemps' => 'Lumière de Printemps', [...]).

      Défaut : lorsque vous voudrez ajouter une nouvelle feuille de style, vous devrez modifier le code de votre page.

    • Utiliser une base de données

      Cela va du fichier INI, parsable avec parse_ini_file, à la table SQL (possédant au minimum deux champs : le nom du dossier et le titre du style), en passant par le fichier XML.

      Défaut : la lourdeur de l'utilisation d'une base de données.

    En résumé, la méthode utilisant une base de données est à réserver aux cas où on ne souhaite pas avoir à modifier (ou bien sûr, à faire modifier) le code source. Elle s'adaptera parfaitement au cas des scripts distribués.

    Par contre, sa relative lourdeur vous encouragera à utiliser la méthode avec array dans le reste des cas : là où vous êtes le codeur, et qu'une flexibilité de votre code à un non-initié serait inutile.
    Par exemple, votre site perso ou votre blog.

    Remarque : vous auriez pu penser à utiliser le nom du dossier, ou le nom du fichier CSS, en tant que titre.
    Cette méthode n'est pas recommandée car elle pose le problème de l'encodage des accents et des espaces.
    De plus, ce n'est pas la plus simple à mettre en œuvre (il faudrait parcourir le répertoire avec opendir puis readdir), ni la plus logique pour le néophyte.

    Dans ce script, nous utiliserons la méthode utilisant un array associatif, mais il sera facilement adaptable à la méthode utilisant une base de données (vous n'aurez qu'à modifier la définition de la variable $styles).

    Passons au code.

    Définition des différents styles et du style préféré

    <?php
    /* définition des différents styles */
    $styles = array(
    'rouge_ciel' => 'Rouge ciel',
    'printemps' => 'Lumière de Printemps',
    'ete' => 'Soleil d\'été',
    'no_style' => 'Pas de style'
    );
     
    /* si le formulaire de changement de style est rempli avec une valeur correcte */
    if(isset($_GET['style']) && array_key_exists($_GET['style'], $styles)) {
            $favorite_style = $_GET['style'];
    }
    /* sinon, on prend la valeur du cookie s'il existe */
    elseif(isset($_COOKIE['favorite_style'])) {
            $favorite_style = $_COOKIE['favorite_style'];
    }
    /* sinon, la valeur par défaut */
    else {
            $favorite_style = 'rouge_ciel';
    }
    ?>
    

    Ce bout de code est à insérer avant l'affichage des pages où vous souhaitez intégrer ce système de styles alternatifs.

    Vous remarquerez un style no_style, correspondant à l'absence de style, utile pour divers handicapés.
    Cette feuille de style sera vide, à l'exception d'un commentaire quelconque (afin éviter un bug sous IE/Mac).

    En cas de changement de la feuille de style favorite

    <?php
    /* si le formulaire est rempli avec une valeur correcte, on envoie un cookie pour se souvenir du choix du visiteur */
    if(isset($_GET['style']) && array_key_exists($_GET['style'], $styles)) {
            setcookie('favorite_style', $_GET['style'], time() + 63115200);
    }
    ?>
    

    Remarque : setcookie doit être placé avant tout envoi au navigateur, vous devez donc placer ce code avant tout affichage.

    Linkage des feuilles de style

    <?php
    /* affichage de la feuille de style favorite */
    echo '<link rel="stylesheet" type="text/css" href="style/'.$favorite_style.'/screen.css" media="screen" title="'.$styles[$favorite_style].'" />'."\n";
     
    /* affichage des feuilles de style alternatives */
    foreach($styles as $key => $value) {
            if($key !== $favorite_style) {
                    echo '<link rel="alternate stylesheet" type="text/css" href="style/'.$key.'/screen.css" media="screen" title="'.$value.'" />'."\n";
            }
    }
    ?>
    

    Si vous avez différents types de media pour chaque style, il vous suffit d'ajouter dans les deux echo une seconde balise <link /> contenant le media voulu.

    Formulaire de changement de style favori

    <form action="" method="get">
    <p>
    <select name="style">
    <?php
    foreach($styles as $key => $value) {
            if($key !== $favorite_style) { // feuilles de style alternatives
                    echo '<option value="'.$key.'">'.$value.'</option>'."\n";
            }
            else { // feuille de style favorite
                    echo '<option value="'.$favorite_style.'" selected="selected">'.$styles[$favorite_style].'</option>'."\n";
            }
    }
    ?>
    </select>
    <input type="submit" value="Envoyer" />
    </p>
    </form>
    

    Conclusion

    Pour finir, voici une page complète intégrant ce système, pouvant servir d'exemple pour vos tests, ou aider à l'intégration du script dans votre site web (les commentaires explicatifs ont été supprimés).

    <?php
    $styles = array(
    'rouge_ciel' => 'Rouge ciel',
    'printemps' => 'Lumière de Printemps',
    'ete' => 'Soleil d\'été',
    'no_style' => 'Pas de style'
    );
    
    if(isset($_GET['style']) && array_key_exists($_GET['style'], $styles)) {
            $favorite_style = $_GET['style'];
    }
    elseif(isset($_COOKIE['favorite_style'])) {
            $favorite_style = $_COOKIE['favorite_style'];
    }
    else {
            $favorite_style = 'rouge_ciel';
    }
    
    if(isset($_GET['style']) && array_key_exists($_GET['style'], $styles)) {
            setcookie('favorite_style', $_GET['style'], time() + 63115200);
    }
    
    echo '<?xml version="1.0" encoding="iso-8859-15"?>'."\n";
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    
    <head>
      <title>Page de test des feuilles de style alternatives</title>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
      <meta http-equiv="Content-Style-Type" content="text/css" />
    
    <?php
    echo '  <link rel="stylesheet" type="text/css" href="style/'.$favorite_style.'/screen.css" media="screen" title="'.$styles[$favorite_style].'" />'."\n";
    
    foreach($styles as $key => $value) {
            if($key !== $favorite_style) {
                    echo '  <link rel="alternate stylesheet" type="text/css" href="style/'.$key.'/screen.css" media="screen" title="'.$value.'" />'."\n";
            }
    }
    ?>
    
    </head>
    
    <body>
    
    <form action="" method="get">
    <p>
    <select name="style">
    <?php
    foreach($styles as $key => $value) {
            if($key !== $favorite_style) {
                    echo '<option value="'.$key.'">'.$value.'</option>'."\n";
            }
            else {
                    echo '<option value="'.$favorite_style.'" selected="selected">'.$styles[$favorite_style].'</option>'."\n";
            }
    }
    ?>
    </select>
    <input type="submit" value="Envoyer" />
    </p>
    </form>
    
    </body>
    </html>
    

    J'espère avoir été clair. Pour toute remarque, suggestion ou critique, n'hésitez pas à utiliser les commentaires ou à m'envoyer un MP. :)

    • Thématiques du cours : PHP Web

    déroulement d'un cours

    • 1

      Dès aujourd'hui, vous avez accès au contenu pédagogique et aux exercices du cours.

    • 2

      Vous progressez dans le cours semaine par semaine. Une partie du cours correspond à une semaine de travail de votre part.

    • !

      Les exercices doivent être réalisés en une semaine. La date limite vous sera annoncée au démarrage de chaque nouvelle partie. Les exercices sont indispensables pour obtenir votre certification.

    • 3

      À l'issue du cours, vous recevrez vos résultats par e-mail. Votre certificat de réussite vous sera également transmis si vous êtes membre Premium et que vous avez au moins 70% de bonnes réponses.

    L'auteur

    Exemple de certificat de réussite
    Exemple de certificat de réussite