WordPress: Développer ses propres widgets

Un précédent article, nous a montré qu’il était assez facile de rendre un thème compatible avec les widgets. Nous avons à notre disposition, un assez grand nombre de widgets disponibles, en plus de ceux présents en standard dans WordPress. Malgré cela, nous pouvons avoir besoin de développer les nôtres pour, par exemple, une meilleure intégration avec notre thème.
Voyons donc maintenant comment développer nos propres widgets

Le développement d’un widget s’effectue en trois étapes:

  1. Création de la fonction PHP qui affichera le widget,
  2. Création de la fonction PHP qui va prendre en charge le panneau de configuration du widget,
  3. Enregistrement des deux fonctions précédentes

Les widgets peuvent être embarqués dans un thème ou dans un plugin. Dans le premier cas, le code PHP doit être placé dans le fichier function.php du thème. Dans le second cas, les fonctions doivent figurer dans le fichier principal du plugin, ou dans un fichier appelé par ce dernier.

Création du widget lui-même

La structure est relativement simple. Lorsque WordPress veut afficher le widget, il utilise la fonction indiquée, en lui transmettant en argument, les options du type before_widget, after_widget… (vu dans l’article Themes et Widgets)
La fonction PHP prend donc la forme suivante:

1
2
3
4
5
6
7
8
9
10
11
function widget_[nom du widget]( $args ) {
	extract( $args );
	$options = get_option( 'widget_[nom du widget]' );
 
	echo $before_widget;
	echo $before_title . $options['title'] . $after_title;
 
	/* Partie principale du widget - Affichage */
 
	echo $after_widget;
}

Application: Affichage de liens RSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function widget_feeds( $args ) {
        $options = get_option('widget_feeds_options');
	extract($args);
	echo $before_widget;
        echo $before_title . $options['feed_title'] . $after_title;
?>
        <ul>
             <li><a href="<?php bloginfo('rss2_url') ?>">RSS for posts</a></li>
             <li><a href="<?php bloginfo('comments_rss2_url'); ?>">
                                    RSS for comments</a></li>
        </ul>
<?php
	echo $after_widget;
}

Création du panneau de configuration

Les fonctions définissant le comportement du panneau de configuration sont plus complexes. Il faut

  • Récupérer les options courantes du widget,
  • Récupérer les valeurs provenant du formulaire (dans le cas de l’appui sur le bouton ‘Modifier’),
  • Affichage du formulaire.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function widget_[nom du widget]_control( $args ) {
        $newoptions = $options = get_option( ... );
        if ( $_POST['submit'] ) {
	       /* Récupération des valeurs,
                    et initialisation de la variable new_options */
        }
        if ( $options != $newoptions ) {
            $options = $newoptions;
            update_option('widget_', $options);
        }
?>
    <label for="id du champ"> Titre du premier champ
        /* Champ du formulaire: balise input, select ... */
    </label>
 
    <label for="id du champ"> Titre du second champ
        /* Champ du formulaire: balise input, select ... */
    </label>
    <input id="id du champ" name="nom du champ" type="hidden" value="1" />

Application: suite de l’exemple précédent. Le panneau de contrôle va nous permettre de saisir le titre du widget.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function widget_feed_control( $args ) {
        $newoptions = $options = get_option('widget_feeds_options');
        if ( $_POST['submit'] ) {
	       $newoptions['feed_title'] = $_POST['feed_title'];
        }
        if ( $options != $newoptions ) {
            $options = $newoptions;
            update_option('widget_feeds_options', $options);
        }
?>
    <label for="feed_title">Title: 
           <input name="feed_title" id="feed_title" 
                      value="<?php echo $options['feed_title']; ?>" />
    </label>
    <input id="id du champ" name="nom du champ" type="hidden" value="1" />

Enregistrement des deux fonctions

Il ne reste donc plus qu’a indiquer à WordPress, l’existence de ces deux nouvelles fonctions. Cet enregistrement s’effectue grâce à deux fonctions: register_sidebar_widget et register_widget_control.

register_sidebar_widget( $name, $output_callback, $classname)

  • $name correspond à la fois au nom et à l’id (identifiant) du widget,
  • $output_callback permet d’indiquer la fonction PHP qui affichera le widget
  • $classname est le style appliqué au widget

register_widget_control($name, $control_callback, $width = '', $height = '')

  • $name correspond à la fois au nom et à l’id (identifiant) du widget,
  • $output_callback permet d’indiquer la fonction PHP qui affichera le panneau de configuration du widget
  • $width et height sont la largeur et hauteur du panneau de configuration.

Conclusion

Grâce à une structure assez ingénieuse, la conception de Widget est relativement facile. Elle demande cependant une certaine rigueur, pour éviter notamment, les conflits ou les interactions possibles entre widgets. Attention également à la « charge » que représente un widget dans l’affichage de vos pages: Plus il y a de widgets, plus la page sera longue à calculer. Il faut donc penser à bien optimiser le code ou se limiter à de simples affichages.

11 thoughts on “WordPress: Développer ses propres widgets”

  1. Mais oui bien sûr, que je suis sot ! Je ne sais pas comment te remercier Emmanuel. Je suis admiratif en tout cas de ta gentillesse et de ton partage de connaissance.

  2. La fonction get_the_category() sans parametres, se refere a l’article « courant ». Sinon tu dois lui indiquer l’id de l’article dont tu veux les categories.
    Donc dans le fichier single.php qui charge le fichier sidebar.php tu dois avoir quelque chose comme:

    if (have_posts()) {
        the_post();
        ... ...
        get_sidebar();
    }
    
  3. Merci pour ces judicieux conseils.
    cela dit, si je mets

    if(is_single())
    $category = get_the_category();
    dynamic_sidebar($category[0]->name);

    ça n’affiche pas la bonne sidebar
    ça affiche la sidebar d’une catégorie dont l’article ne fait même pas partie… Comment ça se fait ?

  4. Je pense que la syntaxe exacte doit plutot etre:
    $category = get_the_category();
    dynamic_sidebar($category[0]->name);

    L’attribut cat_name n’existe pas dans le tableau retourne par la fonction get_the_category.

    Je pense d’ailleurs qu’il ne faut pas utiliser le nom des categories, mais plutot le slug. Avec le nom, tu risques de te heurter a des problemes d’accents, d’espaces … de codage de caracteres. Avec le slug (ou term_id) tu n’auras pas ces problemes.

  5. Je reviens par ici Emmanuel d’abord pour te remercier encore de m’avoir aidé à avancer sur mon problème et aussi pour te demander ton avis sur une dernière chose.

    J’ai codé le fichier function.php pour qu’il crée une zone widgetisable pour chaque catégorie et chaque page. Pour une catégorie « documentation », la zone widgetisable » s’appelle également « documentation ».

    Evidemment pour une catégorie « toto » ou un article de la catégorie « toto », j’affiche dans la sidebar la zone widgetisable « toto ».
    Pour cela, dans sidebar.php, je fais apparaitre la zone widgetisable associée de la manière suivante :

    if(is_category()) {
    $cat = single_cat_title("", false);
    dynamic_sidebar($cat);

    } elseif(is_page()) {
    echo $posts[0]->post_title;
    dynamic_sidebar($posts[0]->post_title);

    } elseif(is_single()) {

    }

    Mon problème se situe sur « single ». J’ai essayé plusieurs choses dont

    $category = get_the_category();
    dynamic_sidebar($category[0]->cat_name;);

    mais ça ne fonctionne pas. Je n’arrive pas à récuperer le nom de la catégorie d’un article pour le mettre dans dynamic_sidebar() lorsque je suis dans un « single ». Tout le reste est ok, mais sur ça je bloque depuis trois jours. Est-que tu aurais une idée ? J’ai l’impression d’avoir tout essayé. Merci.

  6. Merci Emmanuel pour tes réponses (rapides) et le partage de tes connaissances. Ton commentaire m’a bien éclairé.
    Pour ceux que ça aidera :
    Donc mon widget est déclaré ainsi

    function ows1() {
    $options = array(
    'classname' => 'widgetclass', // classe du widget dans la sidebar
    'description' => 'widget se seb' // la description dans l'admin
    );
    // parent::WP_Widget(identifiant, titre, options);
    parent::WP_Widget('titre01', 'mon widget', $options);
    }

    et pour verifier que ce widget est actif j’ecris

  7. Avec l’API 2.8, tu crees les widgets de la facon suivante:

    $widget_ops = array('classname' =&gt; 'CSS class name', 'description' =&gt; 'widget description' );
    $this-&gt;WP_Widget('wigget base id', 'widget title', $widget_ops);

    Comme par défaut, les widgets en WP 2.8 sont multi-instanciables, tu prends l’Id que tu as donne, et tu ajoutes « -numero ».
    Exemple:
    – si ton id est my_widget_id
    – les identifiants seront my_widget_id-1, my_widget_id-2, …

    Pour verifier, visualises la variable $wp_registered_widgets qui contient tous les widgets avec les ids, callback, …

  8. En fait je pensais que l’id ou l’id_base était un identifiant, ou un nom qu’on donnait au widget lorsqu’on le codait et dans ce cas il suffirait que je regarde dans le code pour voir le nom qui lui a été donné. Mais je ne sais pas où.
    Non, ça se passe pas comme ça ?

  9. Je n’ai pas trouve de fonction retournant l’ID d’un widget.
    Eventuellement, tu peux « bricoler » quelque chose a partir de la variable $wp_registered_widgets qui contient la liste de tous les widgets (ne pas oublier de la declarer comme global au prealable).

Laisser un commentaire

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