Créer son widget personnalisé dans WordPress

admin-apparence-widget

Comment Gérer vous présente pas-à-pas la démarche pour créer un widget personnalisé dans WordPress.

Dans l’article Ajouter des champs de profil (informations de contact) dans WordPress, je vous ai montré comment ajouter deux champs supplémentaires dans le profil utilisateur.

L’exemple présenté a permis de créer, pour rappel, deux champs nommés :

  • Facebook Url
  • Twitter Url

Ces deux nouveaux champs ont été précédemment ajoutés dans le but d’être utiliser automatiquement dans un widget personnalisé.

publicités

Ce widget WordPress personnalisé, je l’ai nommé “Réseaux Sociaux”.

L’image en en-tête qui illustre cet article vous montre ce widget.

Il est encadré en rouge.

Après basculement de ce widget dans la sidebar, il est possible de modifier le titre et de sélectionner un utilisateur.

Voici comment il apparaît dans la partie widget de l’administration de WordPress :

admin-sidebar-widget

Après avoir sélectionné l’utilisateur (ce n’est pas montré ici mais j’ai sélectionné mon profil) et cliqué sur “Enregistrer”, le widget apparaît désormais dans ma colonne de droite ainsi :

site-sidebar-widget

Voilà, le résultat que je souhaitais obtenir.

Maintenant, je vais vous montrer comment faire.

Prédicats

Voici ce qu’il faut prendre en compte pour bien comprendre la suite de ce tutoriel :

  • La création de deux champs supplémentaires dans le profil utilisateur (expliqué pour rappel dans Ajouter des champs de profil (informations de contact) dans WordPress)
  • Ce widget est créé au sein d’un plugin (que j’ai créé également), en changeant très peu de paramètres, l’exemple peut être reproduit dans votre fichier functions.php (ou dérivé) de votre thème enfant
  • Les étapes de déclaration du plugin ne sont pas montrées ici (sous-entendu que vous l’avez déjà fait)
  • La déclaration du domaine de texte n’est pas montrée ici (sous-entendu que vous l’avez également déjà fait – les tableaux récapitulatifs pour préparer vos traductions de plugin ou de thème WordPress peuvent éventuellement vous aider)
  • Les exemples en ce qui concerne en particulier les variables sont présentées en français par facilité mais n’oubliez pas que normalement le développement se fait en anglais
  • Dans l’exemple, le nom de la classe du Widget déclarée est Widget_Social
  • Dans l’exemple, j’ai nommé le text-domain en français texte-domaine que vous devez personnaliser selon le votre
  • Les balises sont en HTML5.

Maintenant, commençons réellement :

Etape 1 : Initialiser votre Widget Personnalisé

Pour initialiser votre Widget dans WordPress, voici le détail :

<?php
add_action(
 'widgets_init',
 function() {
  register_widget( 'Widget_Social' );
  }
 );
?>

Exactement la même chose mais sur une seule ligne :

<?php add_action( 'widgets_init', function(){ register_widget( 'Widget_Social' ); } ); ?>

Cependant, on ne va pas laisser cela comme ça. On va prendre une précaution par rapport à la version PHP installée selon le serveur. En effet, l’initialisation du widget n’est pas la même selon la version de PHP.

Donc le mieux est d’utiliser, cette version de code :

<?php
if ( version_compare(PHP_VERSION, '5.3.0') >= 0 ) {
 // PHP 5.3+ seulement
 add_action( 'widgets_init', function(){ register_widget( 'Widget_Social' ); } );
}
elseif ( version_compare(PHP_VERSION, '5.2.0') >= 0 ) {
 // PHP 5.2+
 add_action( 'widgets_init', create_function( '', 'return register_widget("Widget_Social");' ) );
}
else {
 // Petit message si la version PHP est inférieure à 5.2.0
 echo __( 'Votre version PHP est', 'texte-domaine' ) . ' ' . phpversion() . '. ';
 echo __( 'Besoin 5.2.0+. Merci de faire une mise à jour.', 'texte-domaine' );
}
?>

Etape 2 : Ajouter le widget

Tout ce qui suit dans l’étape 2 est englobée dans une classe Widget_Social qui est la prolongement ou l’extension de la classe WP_Widget :

<?php
class Widget_Social extends WP_Widget {
// Le code qui suit en étape 2.1, 2.2, 2.3 et 2.4
}
?>

Etape 2.1 : Enregistrer le widget

function __construct() {
 parent::__construct(
  // Base ID
  'social-widget',
  // le nom qui apparaît en titre du Widget
  __( 'Réseaux Sociaux', 'texte-domaine' ),
  // Argument : ici, c'est juste la description
  array(
   'description' => __( 'Déplacez ce widget dans la sidebar pour montrer vos réseaux sociaux.', 'texte-domaine' ),
  )
 );
}

Et en image, voici comment le widget “Réseaux Sociaux” apparaît dans la partie administration “Apparence” de WordPress :

admin-apparence-widget

Ce widget est pour le moment juste pour moi, mais je me vouvoie. 😉

Etape 2.2 : Personnalisation Widget côté back-end (côté administration)

Accrochez-vous ! Cette étape est un peu compliquée. J’ai mis moi-même du temps pour tout assimiler. Prenez le temps de bien comprendre. J’ai mis de nombreuses explications. Si cela ne suffit pas, n’hésitez pas à demander dans les commentaires. Je répondrais si je peux vous aider selon mes compétences.

// form() est une fonction de WP_Widget
public function form( $instance ) {
 
// Si le titre n'est pas vide, alors on met le titre, sinon un nouveau titre
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Nouveau titre', 'texte-domaine' );
 
// Si l'utilisateur n'est pas vide, alors on met l'utilisateur, sinon un nouveau utilisateur
$user = ! empty( $instance['user'] ) ? $instance['user'] : ($instance['user'] = $_POST['user']);
 
// La balise d'ouverture <?php se trouve en début d'étape 2
?>
 
<!-- Personnalisation de l'affichage du titre du widget -->
<p>
 <label for="<?php echo $this->get_field_id( 'title' ); ?>">
  <?php _e( 'Titre :', 'texte-domaine' ); ?>
 </label>
<!-- class="widefat" est une classe CSS WordPress -->
 <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>"
  name="<?php echo $this->get_field_name( 'title' ); ?>"
  type="text" value="<?php echo $title; ?>">
</p>
 
<!-- Sélection de l'utilisateur -->
<p>
 <label for="<?php echo $this->get_field_id( 'user' ); ?>"></label>
 
 <?php
 // On récupère la liste des utilisateurs
 wp_dropdown_users(array(
  'show_option_none'  => __( 'Select user', 'texte-domaine' ),
  'selected'          => $user,
 ));
 ?>
 
 <input id="<?php echo $this->get_field_id( 'user' ); ?>"
  name="<?php echo $this->get_field_name( 'user' ); ?>"
  type="hidden" value="<?php echo $instance['user'] = $_POST['user']; ?>">
 
</p>
 
// pour la suite étape 2.3, on ouvre la balise php qui sera fermée plus tard
<?php
}

Et voici en image, ce que cela donne :

admin-sidebar-widget

Ca va vous êtes toujours parmi nous ? Cette étape était assez difficile. On mélange du PHP, de l’HTML, de la programmation objet (et ce n’est pas trop mon fort)… mais quand on s’y penche et on prend bien le temps de regarder ligne par ligne alors ça devient un peu plus simple à comprendre.

Etape 2.3 : Affichage et Personnalisation du Widget côté front-end (côté client)

Le widget a été déplacé dans la colonne et a été enregistré côté back-end (côté administration).

Maintenant, le but de tout ceci est de l’afficher sur le site dans la colonne avec les informations liées aux réseaux sociaux préalablement enregistrés dans le profil utilisateur.

Pour cela, dans cette partie, on récupère les variables de l’utilisateur et les variables des champs enregistrés dans le champ de profil de ce même utilisateur.

Et on prépare la mise en forme du widget et ce qu’il va afficher réellement.

Je vous rassure cette étape est un peu plus simple à comprendre, normalement…

// widget() est une fonction WP_Widget
public function widget( $args, $instance ) {
 
 // Affichage début du widget
 echo $args['before_widget'];
 
 if ( ! empty( $instance['title'] ) ) {
  // Affichage du nom qui apparaît en titre du widget
  echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
 }
 
 // Récupère les variables id utilisateurs
 $user_id        = $instance['user'];
 
 // Récupère les variables. Cf: Ajouter des champs de profil (informations de contact) dans WordPress
 $facebook       = get_the_author_meta( 'facebook', $user_id );
 $twitter        = get_the_author_meta( 'twitter', $user_id );
 
 // Personnalise dans le lien le titre des champs de profil
 $titlefacebook  =  __( 'Aimez sur Facebook', 'texte-domaine' );
 $titletwitter   =  __( 'Suivez sur Twitter', 'texte-domaine' );
 
 echo '<div class="textwidget">';
 
 if ( !empty($facebook) ) {
  echo '<p><a href="' . $facebook. '" title="' . $titlefacebook .'" target="_blank">
   <img src="' . plugins_url( 'images/facebook.jpg', __FILE__ ) . '" width="160" height="45" alt="' . $titlefacebook . '">
   </a></p>';
 }
 
 if ( !empty($twitter) ) {
  echo '<p><a href="' . $twitter. '" title="' . $titletwitter .'" target="_blank">
   <img src="' . plugins_url( 'images/twitter.jpg', __FILE__ ) . '" width="160" height="45" alt="' . $titletwitter . '">
   </a></p>';
 }
 
 echo '</div>';
 
 // Affichage fin du widget
 echo $args['after_widget'];
}

Note : Pour les lignes 27 et 33, vous avez le chemin vers les images indiquées comme ceci <img src="' . plugins_url( 'images/facebook.jpg', __FILE__ ) . '">. Cela sous-entend que les images sont dans un dossier nommé “images” et que le chemin se trouve dans le dossier du plugin correspondant. Si par exemple, je veux demander le chemin des images dans le sous-dossier du thème enfant, je mettrais ce code pour la source de mon image <img src="' . get_stylesheet_directory_uri() . '/images/facebook.jpg"> à la place de ligne 27.

Et en image, voici ce que cela donne :

site-sidebar-widget

Vous pouvez aussi le voir directement sur ce site.

Etape 2.4 : Nettoyage et mise à jour des informations sauvegardées dans le Widget

Vous avez cru que c’était fini ? Et bien non, quand il y en n’a plus, il y en a encore.

Cette étape est très rapide comparée aux précédentes. Elle permet de nettoyer et mettre à jour les informations envoyées dans le widget côté back-end pour les sauvegarder dans la base de données.

Note : Cela ne concerne que les informations données dans ce widget et rien d’autres. C’est-à-dire que les champs facebook et twitter ne sont pas vérifiées ici. Ceci a été fait au préalable.

// update() est une fonction de WP_Widget
public function update( $new_instance, $old_instance ) {
 
 $instance = array();
 $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
 $instance['user'] = ($new_instance['user'] = $_POST['user']);
 
 return $instance;
}

Et voilà, fin de l’étape 2 avec ces 4 sous-étapes.

Le widget “Réseaux sociaux” a été créé, enregistré, sauvegardé et affiché.

Résumé de la personnalisation d’un widget WordPress

Vous allez me dire que pour afficher uniquement deux liens vers des réseaux sociaux avec leurs images, il y a carrément plus simple. Et vous avez raison.

L’idée est de montrer une méthode pour créer ses propres widgets personnalisés et pouvoir les dupliquer pour d’autres applications comme par exemple pour pouvoir le réutiliser facilement dans la personnalisation de plusieurs thèmes WordPress (c’est mon réel objectif).

Le code complet de création widget personnalisé pour WordPress

Pour finir, je vous donne le code complet des étapes 1 et 2 dont les sous-étapes 2.1., 2.2., 2.3 et 2.4 avec les commentaires précédents en moins et quelques nouveaux.

<?php
/* Initialise Widget */
if ( version_compare(PHP_VERSION, '5.3.0') >= 0 ) {
 add_action( 'widgets_init', function(){ register_widget( 'Widget_Social' ); } );
}
elseif ( version_compare(PHP_VERSION, '5.2.0') >= 0 ) {
 add_action( 'widgets_init', create_function( '', 'return register_widget("Widget_Social");' ) );
}
else {
 echo __( 'Votre version PHP est', 'texte-domaine' ) . ' ' . phpversion() . '. ';
 echo __( 'Besoin 5.2.0+. Merci de faire une mise à jour.', 'texte-domaine' );
}
 
/**
 * Ajoute Widget_Social
 *
 * Widget Réseaux Sociaux
 */
class Widget_Social extends WP_Widget {
function __construct() {
 parent::__construct(
  'social-widget',
  __( 'Réseaux Sociaux', 'texte-domaine' ),
  array(
   'description' => __( 'Déplacez ce widget dans la sidebar pour montrer vos réseaux sociaux.', 'texte-domaine' ),
  )
 );
}
 
/**
 * Formulaire widget Back-end
 *
 * @voir WP_Widget::form()
 *
 * @param array $instance Valeurs précédemment enregistrées dans base de données
 */
public function form( $instance ) {
 
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Nouveau titre', 'texte-domaine' );
$user = ! empty( $instance['user'] ) ? $instance['user'] : ($instance['user'] = $_POST['user']);
 
?>
 
<p>
 <label for="<?php echo $this->get_field_id( 'title' ); ?>">
  <?php _e( 'Titre :', 'texte-domaine' ); ?>
 </label>
 <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>"
  name="<?php echo $this->get_field_name( 'title' ); ?>"
  type="text" value="<?php echo $title; ?>">
</p>
 
<p>
 <label for="<?php echo $this->get_field_id( 'user' ); ?>"></label>
 
 <?php
 wp_dropdown_users(array(
  'show_option_none'  => __( 'Select user', 'texte-domaine' ),
  'selected'          => $user,
 ));
 ?>
 
 <input id="<?php echo $this->get_field_id( 'user' ); ?>"
  name="<?php echo $this->get_field_name( 'user' ); ?>"
  type="hidden" value="<?php echo $instance['user'] = $_POST['user']; ?>">
 
</p>
 
<?php
}
 
/**
 * Affichage du widget en front-end
 *
 * @voir WP_Widget::widget()
 *
 * @param array $args     Widget arguments
 * @param array $instance Valeurs sauvegardées dans la base de données
 */
public function widget( $args, $instance ) {
 
 echo $args['before_widget'];
 
 if ( ! empty( $instance['title'] ) ) {
  echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
 }
 
 $user_id        = $instance['user'];
 
 $facebook       = get_the_author_meta( 'Facebook', $user_id );
 $twitter        = get_the_author_meta( 'twitter', $user_id );
 
 $titlefacebook  =  __( 'Aimez sur Facebook', 'texte-domaine' );
 $titletwitter   =  __( 'Suivez sur Twitter', 'texte-domaine' );
 
 echo '<div class="textwidget">';
 
 if ( !empty($facebook) ) {
  echo '<p><a href="' . $facebook. '" title="' . $titlefacebook .'" target="_blank">
   <img src="' . plugins_url( 'images/facebook.jpg', __FILE__ ) . '" width="160" height="45" alt="' . $titlefacebook . '">
   </a></p>';
 }
 
 if ( !empty($twitter) ) {
  echo '<p><a href="' . $twitter. '" title="' . $titletwitter .'" target="_blank">
   <img src="' . plugins_url( 'images/twitter.jpg', __FILE__ ) . '" width="160" height="45" alt="' . $titletwitter . '">
   </a></p>';
 }
 
 echo '</div>';
 
 echo $args['after_widget'];
}
 
/**
 * Nettoie les valeurs des formulaires widget et mise à jour
 *
 * @voir WP_Widget::update()
 *
 * @param array $new_instance Valeurs envoyés pour être sauvegardé
 * @param array $old_instance Valeurs précédemment sauvegardées de la base de données
 * @return array Mise à jour des valeurs nettoyées pour être sauvegardée
 */
 public function update( $new_instance, $old_instance ) {
 
  $instance = array();
  $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
  $instance['user'] = ($new_instance['user'] = $_POST['user']);
 
  return $instance;
 }
}
?>

Partager cette page Comment Gérer :

2 avis sur " Créer son widget personnalisé dans WordPress "

  • Agnes

    avatar Agnes écrit le lundi 27 juin 2016 à 16:33

    Super tuto
    cependant je ne comprends pas ou mettre tout ce code. Pas dans functions.php..?

    • Benoît de Comment Gérer

      avatar Benoît de Comment Gérer écrit le mardi 28 juin 2016 à 02:02

      Bonjour Agnès,

      Merci pour votre message.

      Comme indiqué dans le chapitre “Prédicats”, vous pouvez créer votre propre plugin (extension) ou insérer votre code directement dans votre fichier functions.php.

      Si vous ne savez pas créer un plugin, je vous conseille de créer un fichier à part que vous nommez par exemple mon-widget.php et de le placer dans le dossier de votre thème enfant. Puis de suivre ce tuto.

      Et ajoutez dans votre fichier functions.php la ligne suivante (si votre fichier est dans le même dossier que votre thème enfant, sinon à vous d’adapter) :

      require_once get_stylesheet_directory().'mon-widget.php';

      Bon développement,

      Benoît

Laisser un commentaire

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

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strong>