Créer une page d’options de thème dans WordPress

Ajouter une page de configuration de thème Wordpress dans la partie administration.

Il y a quelques temps de cela, ajouter une page de réglages de thème dans la partie administration de WordPress était une tache plutôt difficile, il n’y avait pas beaucoup d’outils, il fallait mettre les mains dans le cambouis. Depuis la version 2.7 de WordPress, les Settings API simplifient grandement la mise en place d’une (ou plusieurs) page d’options. Outre cet énorme avantage d’avoir les outils à portée de main, utiliser les API fournies par WordPress permet d’accroitre la sécurité et l’extensibilité de votre thème.

Description

Dans cet article, nous allons créer une simple page d’options, celle-ci fournira un formulaire qui permettra de choisir (boutons radio) entre un gabarit avec barre latérale à gauche ou à droites et de fixer un texte de copyright. Note : ce tutoriel décrit la création de la page d’administration d’un thème imaginaire, nous n’allons pas créer le thème lui-même, mais pour pouvoir avoir un tutoriel fonctionnel, un petit thème enfant du Twenty Eleven de WordPress sera disponible afin de tester notre panneau d’options et de voir le résultat sur ce thème enfant.

Afin d’éviter des conflits avec d’autres plugins ou thèmes et de faire les choses proprement, nous allons préfixer nos fonctions et les options avec « werk_ ».

Architecture des fichiers

Avant de commencer à écrire du code, un petit mot sur la structure des fichiers. Tout ce qui est relatif à notre page d’options résidera dans le fichier theme-options.php à la racine du thème. Il est pré-supposé que le thème possède déjà un fichier functions.php avec des fonctions à vous, si ce n’est pas le cas, il suffit de le créer avec la ligne ci-dessous dedans, qui appelle le fichier d’options :

require_once ( get_stylesheet_directory() . '/theme-options.php' );

theme-options.php

Pour entrer dans le vif du sujet, on commence par enregistrer les options que nous allons utiliser grâce à la fonction register_setting :

function werk_register_settings() {
	register_setting( 'werk_theme_options', \
		'werk_options', 'werk_validate_options' );
}
add_action( 'admin_init', 'werk_register_settings' );

Cette fonction register_setting doit être appelée depuis une fonction crochetée à l’action admin_init ou celle-ci retournera une erreur de fonction non déclarée. Nous allons utiliser un tableau contenant les réglages que nous avons besoin pour le thème. Voici la signification des paramètres :

  1. Groupe d’options,
  2. nom de notre paramètre,
  3. nom de la fonction qui va nettoyer les valeurs envoyées par le formulaire. Cette étape est optionnelle, mais est importante pour la sécurité de WordPress.

A ce stade, rien ne se passe bien entendu car aucune valeur n’existe, il faut les initialiser. Pour ce faire, nous ajoutons un tableau avec les valeurs par défaut :

$werk_options = array(
	'copyright' => '© ' . date('Y') . get_bloginfo('name'),
	'barre' => 'gauche'
);

Comme vous pouvez le voir, notre texte de copyright sera « © 2011 Nom du Site » et la barre latérale sera à gauche par défaut. Bien entendu, ces valeurs sont pour le moment uniquement placées dans un tableau pour une utilisation ultérieure, pour les rendre effectives, il faudra – dans les fichiers du thème – passer ces valeurs comme second paramètre de la fonction get_option :

$werk_settings = get_option( 'werk_options', $werk_options )

Les valeurs par défaut sont prises en compte, il faut maintenant afficher les autres valeurs possibles dans un formulaire de choix d’options. Ces choix seront également placés dans un tableau contenant la valeur et le libellé des éléments de formulaire :

$werk_barre = array(
	'gauche' => array(
		'value' => 'gauche',
		'label' => 'Barre latérale gauche'
	),
	'droite' => array(
		'value' => 'droite',
		'label' => 'Barre latérale droite'
	),
);

Il est temps de créer la page d’options avec la fonction add_theme_page :

function werk_theme_options() {
	add_theme_page( 'Nos Options', 'Nos Options', \
	'edit_theme_options', 'werk_theme_options', \
	'werk_theme_options_page' );
}
add_action( 'admin_menu', 'werk_theme_options' );

Comme pour admin_init, cette fonction a besoin d’être appelée depuis une fonction crochetée à l’action admin_menu afin d’éviter une erreur de fonction non déclarée. La fonction va ajouter un sous-menu sous le menu Apparence de l’administration de WordPress. C’est l’endroit recommandé pour les pages d’options de thème. Voici les paramètres de cette fonction :

  1. Titre du document dans la barre de titre du navigateur,
  2. nom du sous-menu sous le menu Apparence,
  3. il s’agit du paramètre de capability nécessaire à un utilisateur pour accèder à la page. Pour nous, il est définit à edit_theme_options,
  4. le slug de la page, ce qui apparaitra dans l’URL,
  5. le dernier paramètre est la fonction qui va générer la page.

Voyons maintenant comment implémenter le formulaire de notre page. Celui-ci se définit dans la fonction werk_theme_options_page ci-dessous. Voir les commentaires dans le code pour une explication détaillée.

// Construction et affichage de la page et du formulaire
function werk_theme_options_page() {
    // On inclut nos tableaux globaux
    global $werk_options, $werk_barre;
    
    // Valide la soumission du formulaire
    if ( ! isset( $_REQUEST['settings-updated'] ) )
        $_REQUEST['settings-updated'] = false;
    ?>

    <div class="wrap">

    <?php
    // Affiche le nom de la page et son icone si celle-ci a été définie
    screen_icon();
    echo "<h2>" . get_current_theme() . __( ' Nos Options' ) . "</h2>";
    ?>

    <?php
    // Si le formulaire vient juste d'etre soumis, affiche une notification
    if ( false !== $_REQUEST['settings-updated'] ) : ?>
    <div class="updated fade">
    <p><strong><?php _e( 'Options sauvegardées' ); ?></strong></p>
    </div>
    <?php endif;?>

    <form method="post" action="options.php">

    <?php $settings = get_option( 'werk_options', $werk_options ); ?>

    <?php
    // Cette fonction retourne plusieurs champs cachés requis par le formulaire,
    // parmis lesquels un nonce ("number used once"), un nombre unique utilisé
    // pour s'assurer que le formulaire n'ait été envoyé que depuis la page
    // d'administration. Très important pour la sécurité.
    settings_fields( 'werk_theme_options' );
    ?>

    <table class="form-table"><!-- Désolé pour les tables ^.^ -->

    <tr valign="top">
    <th scope="row">
    <label for="werk_copyright">Texte du Copyright</label>
    </th>
    <td>
    <input id="werk_copyright" name="werk_options[werk_copyright]" type="text"
        value="<?php  esc_attr_e($settings['werk_copyright']); ?>" />
    </td>
    </tr>

    <tr valign="top"><th scope="row">Barre latérale</th>
    <td>
    <?php foreach( $werk_barre as $barre ) : ?>
    <input type="radio" id="<?php echo $barre['value']; ?>" name="werk_options[barre]"
        value="<?php esc_attr_e( $barre['value'] ); ?>"
        <?php checked( $settings['barre'], $barre['value'] ); ?> />
    <label for="<?php echo $barre['value']; ?>">
        <?php echo $barre['label']; ?></label><br />
    <?php endforeach; ?>
    </td>
    </tr>
    
    </table>

    <p class="submit"><input type="submit" class="button-primary"
        value="Enregistrer" /></p>
    </form>

    </div>

    <?php
}

Et le code de la fonction de nettoyage :

function werk_validate_options( $input ) {
    global $werk_options, $werk_barre;

    $settings = get_option( 'werk_options', $werk_options );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_copyright'] = wp_filter_nohtml_kses( $input['werk_copyright'] );

    /* Nous sauvegardons la valeur du champ pour le restaurer en cas d'une entrée non valide */
    $prev = $settings['barre'];
    // Vérification que l'entrée existe dans le tableau
    if ( !array_key_exists( $input['barre'], $werk_barre ) )
        $input['barre'] = $prev;

    return $input;
}

Téléchargement

Afin de pouvoir tester tout ceci, vous pouvez télécharger ce petit bundle que j’ai préparé et qui est un thème enfant du Twenty Eleven. Installez-le comme n’importe quel thème et voyez le résultat.

Installation du thème en images

8 thoughts on “Créer une page d’options de thème dans WordPress”

  1. Merci Beaucoup!! Excellent Tuto, ça marche nickel pour moi alors que je ne sais pas coder et que je suis plutôt un adepte du « bon, ce truc sert ça, donc si je fais ça…. ». Preuve que ce tuto est bien fait !
    Par ailleurs, pour les images, j’ai pu intégrer l’uploader wordpress au formulaire grâce à ce tuto http://www.webmaster-source.com/2010/01/08/using-the-wordpress-uploader-in-your-plugin-or-theme/
    Et ça marche nickel.
    Il ne manque plus qu’une chose à ma page d’option pour être parfaite : Un bouton « paramètres par défaut ». Je cherche en effet un moyen pour que le formulaire recharger les paramètre par défaut dans les champs laissés vide ou suite à un clique sur un bouton reset. J’ai bien cherché sur google mais je ne trouve pas grand chose… Aurais-tu une idée ?

    1. Si je comprends bien ce que tu veux faire, cela me parait simple. Tu ajoutes un tableau avec les valeurs par défaut, qui sera utilisé lorsque l’utilisateur cliquera sur le bouton correspondant.
      Tu dis ne pas savoir coder, il serait vraiment bien de lire un peu les bases de PHP pour pouvoir faire de petits changements come ça ;>
      En tout cas merci pour ton commentaire et content qu’il t’ait servi.

  2. Salut !

    Excellent tutoriel ! Cependant en modifiant « theme-options.php », les valeurs par défaut que je mettais ne s’affichaient pas dans panneau admin par la suite.

    Voici le code source que j’ai pour « theme-options.php », pourrais tu me dire ou est mon erreur ? :


    'black',
    'werk_copyright2' => 'black',
    'werk_background_color' => 'black',
    'werk_background_image' => 'black',
    'werk_background_texte_color' => 'black'
    );

    // Enregistrement des paramètres
    function werk_register_settings() {
    register_setting( 'werk_theme_options', 'werk_options', 'werk_validate_options' );
    }
    add_action( 'admin_init', 'werk_register_settings' );

    // Ajout de la page dans le menu d'administration de WordPress
    function werk_theme_options() {
    add_theme_page( 'Nos Options', 'Nos Options', 'edit_theme_options', 'werk_theme_options', 'werk_theme_options_page' );
    }
    add_action( 'admin_menu', 'werk_theme_options' );

    // Construction et affichage de la page et du formulaire
    function werk_theme_options_page() {
    // On inclut nos tableaux globaux
    global $werk_options;

    // Valide la soumission du formulaire
    if ( ! isset( $_REQUEST['settings-updated'] ) )
    $_REQUEST['settings-updated'] = false;
    ?>

    <?php
    // Affiche le nom de la page et son icone si celle-ci a été définie
    screen_icon();
    echo "" . get_current_theme() . __( ' Nos Options' ) . "";
    ?>

    Texte du Copyright

    <input id="werk_copyright" name="werk_options[werk_copyright]" type="text"
    value="" />

    Your copyright :

    <input id="werk_copyright2" name="werk_options[werk_copyright2]" type="text"
    value="" />

    Background color :

    <input id="werk_background_color" name="werk_options[werk_background_color]" type="text"
    value="" />

    Background image:

    <input id="werk_background_image" name="werk_options[werk_background_image]" type="text"
    value="" />

    Text color:

    <input id="werk_background_texte_color" name="werk_options[werk_background_texte_color]" type="text"
    value="" />

    <?php
    }

    // Fonction de nettoyage
    function werk_validate_options( $input ) {
    global $werk_options;

    $settings = get_option( 'werk_options', $werk_options );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_copyright'] = wp_filter_nohtml_kses( $input['werk_copyright'] );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_copyright2'] = wp_filter_nohtml_kses( $input['werk_copyright2'] );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_background_color'] = wp_filter_nohtml_kses( $input['werk_background_color'] );

    return $input;
    }

    1. Merci pour ton commentaire et je suis content si l’article a pu t’aider. Je pense que la première partie de ton code a été tronquée dans le commentaire..

  3. ‘black’,
    ‘werk_copyright2’ => ‘black’,
    ‘werk_background_color’ => ‘black’,
    ‘werk_background_image’ => ‘black’,
    ‘werk_background_texte_color’ => ‘black’
    );

    // Enregistrement des paramètres
    function werk_register_settings() {
    register_setting( ‘werk_theme_options’, ‘werk_options’, ‘werk_validate_options’ );
    }
    add_action( ‘admin_init’, ‘werk_register_settings’ );

    // Ajout de la page dans le menu d’administration de WordPress
    function werk_theme_options() {
    add_theme_page( ‘Nos Options’, ‘Nos Options’, ‘edit_theme_options’, ‘werk_theme_options’, ‘werk_theme_options_page’ );
    }
    add_action( ‘admin_menu’, ‘werk_theme_options’ );

    // Construction et affichage de la page et du formulaire
    function werk_theme_options_page() {
    // On inclut nos tableaux globaux
    global $werk_options;

    // Valide la soumission du formulaire
    if ( ! isset( $_REQUEST[‘settings-updated’] ) )
    $_REQUEST[‘settings-updated’] = false;
    ?>

    <?php
    // Affiche le nom de la page et son icone si celle-ci a été définie
    screen_icon();
    echo " » . get_current_theme() . __( ‘ Nos Options’ ) . «  »;
    ?>

    Texte du Copyright

    <input id="werk_copyright" name="werk_options[werk_copyright]" type="text"
    value=" » />

    Your copyright :

    <input id="werk_copyright2" name="werk_options[werk_copyright2]" type="text"
    value=" » />

    Background color :

    <input id="werk_background_color" name="werk_options[werk_background_color]" type="text"
    value=" » />

    Background image:

    <input id="werk_background_image" name="werk_options[werk_background_image]" type="text"
    value=" » />

    Text color:

    <input id="werk_background_texte_color" name="werk_options[werk_background_texte_color]" type="text"
    value=" » />

    <?php
    }

    // Fonction de nettoyage
    function werk_validate_options( $input ) {
    global $werk_options;

    $settings = get_option( 'werk_options', $werk_options );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_copyright'] = wp_filter_nohtml_kses( $input['werk_copyright'] );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_copyright2'] = wp_filter_nohtml_kses( $input['werk_copyright2'] );

    // Afin d'éviter des vulnérabilités comme XSS, on enlève toute balise HTML
    $input['werk_background_color'] = wp_filter_nohtml_kses( $input['werk_background_color'] );

    return $input;
    }

  4. J’imagine que la première partie est quelque chose comme ça :


    $werk_options = array(
    'werk_copyright1' => 'black',
    'werk_copyright2' => 'black',
    'werk_background_color' => 'black',
    'werk_background_image' => 'black',
    'werk_background_texte_color' => 'black'
    );

    Cela me semble bon.

    1. Je pense que les valeurs par défaut ont été remplacées. Les valeurs du tableau $werk_options ne servent qu’à initialiser les variables la toute première fois que tu accèdes au panneau d’administration. Dès lors que tu sauvegardes les paramètres à l’aide du bouton « Enregistrer », un enregistrement est ajouté dans la base de données dans la table wp_options, avec dans notre cas « werk_options » pour le champ option_name et une chaine JSON dans option_value qui ressemble à cela avec tes valeurs par défaut :


      a:5:{s:14:"werk_copyright";s:5:"black";
      s:15:"werk_copyright2";s:5:"black";
      s:21:"werk_background_color";
      s:5:"black";s:21:"werk_background_image";
      s:5:"black";s:27:"werk_background_texte_color";
      s:5:"black";}

      Il faut donc supprimer l’enregistrement « werk_options » de la table, ensuite tu peux essayer de revenir sur la page d’options et tu devrais voir tes valeurs par défaut.

Laisser un commentaire

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