Créer un widget de contact complet sur WordPress

Mathieu Chartier CMS (WordPress...) 0 commentaire

WordPress est rempli de bonnes intentions mais ne permet pas toujours d’obtenir ce que l’on cherche, il faut parfois mettre les mains dans le code pour créer des systèmes personnalisés à la hauteur de nos attentes. Il existe heureusement de nombreux plugins (et par extension beaucoup de widgets) qui peuvent apporter des suppléments d’âme à nos sites web mais souvent, l’accumulation d’extensions surcharge le code et le serveur avec des requêtes complémentaires et parfois lourdes.

Notre objectif est donc simple ici, nous voulons créer un petit widget de contact (personnalisable en CSS) qui permet d’afficher nos informations de contact (numéro de téléphone, email, adresse postale…). Le rôle d’un tel widget est d’éviter aux débutants de devoir rentrer ce type d’informations en dur dans le fichier sidebar.php ou dans footer.php par exemple, il suffira ici d’avoir une zone de dépôt de widget et toutes les informations pourront être modifiées en ligne, sans « code HTML ». :D

Vous pouvez télécharger le code complet dans le pack ci-dessous (avec icône, CSS, etc.) ou aller en bas de l’article pour le découvrir. Il ne s’agit que d’un exemple d’usage qui ressemble à la capture présentée ci-après…

Télécharger “Widget contact 1.0”widget-contact.zip – Téléchargé 1140 fois – 123,12 Ko

Widget de contact (code) sur WordPress

Prérequis sur les widgets WordPress

Les widgets WordPress se programment en partie en PHP objet (POO) en créant une classe fille de la classe WP_Widget native. Cette nouvelle classe doit prendre quatre méthodes que nous retrouverons dans le code suivant, voici leur rôle :

  • une méthode permet d’afficher le widget dans le liste des widgets WordPress ;
  • une seconde méthode gère l’affichage final des données (placée en seconde position dans mon code mais ce n’est pas forcément le plus « logique », chacun ordonne comme il le souhaite !) ;
  • une troisième recueille les informations mises à jour et les enregistre en mémoire ;
  • l’ultime méthode correspond au formulaire présenté dans le backoffice lorsque nous activons le widget.

L’objectif est de fournir assez d’informations de contact pour que le widget ait un intérêt. L’exemple de code présenté ci-dessous est modulable, il est possible d’ajouter ou de déplacer les champs présentés selon vos besoins au sein du code (tout est commenté, ça ne devrait pas être trop compliqué). Chaque ligne laissée vide dans le widget n’affichera pas l’information correspondante, c’est bien pratique…

Pour éviter d’utiliser des extensions externes, nous allons ajouter le code dans le fichier functions.php de notre thème WordPress qui est destiné à recevoir toutes les fonctionnalités qui nous intéressent. Il faudra ensuite utiliser la fonction register_widget('NOM_DU_WIDGET'); pour valider son utilisation.

Le code du widget de contact pour WordPress

Parce que les codes valent plus que les longs discours, voici le code complet du widget présenté ci-dessus.

<?php
/*--- Création d'un widget perso ---*/
class WidgetPerso extends WP_Widget {
	function WidgetPerso() {
		// Texte à afficher dans la liste des widgets
		$options = array(
                "classname" => 'contact-aside',
                "description" => 'Affiche les informations de contact entrées dans le widget'
        );
    	$this->WP_widget("Contact", "Contact personnel", $options);
	}

	function widget($arguments, $instance) {
		// Récupération des données
		extract($arguments);
		
		// Informations récupérées par le widget
		$image		= apply_filters('widget_image', $instance['image']);
		$titre		= apply_filters('widget_title', $instance['titre']);
		$imgperso	= apply_filters('widget_imgperso', $instance['imgperso']);
		$telephone	= apply_filters('widget_telephone', $instance['telephone']);
		$portable	= apply_filters('widget_portable', $instance['portable']);
		$email		= apply_filters('widget_email', $instance['email']);
		$rue		= apply_filters('widget_rue', $instance['rue']);
		$complement	= apply_filters('widget_complement', $instance['complement']);
		$codepostal	= apply_filters('widget_codepostal', $instance['codepostal']);
		$ville		= apply_filters('widget_ville', $instance['ville']);
		$pays		= apply_filters('widget_pays', $instance['pays']);

		/* ----------------------------------------------------------------------- */
		/* --------------------------- Code du widget ---------------------------- */
		/* ----------------------------------------------------------------------- */		
		// Début du widget
		echo $before_widget;

		// Formatage de l'affichage final (personnaliser l'ordre, etc.)
		$affichage = "\n".'<div class="contact-aside">'."\n";
		
			// Affichage conditionnel de l'image d'entête
			if($image == true) {
				$affichage.= '<img src="'.get_template_directory_uri().'/contact.png" alt="" class="imgcontact" />'."\n";
			}
			// Affichage conditionnel du titre
			if(!empty($titre)) {
				$affichage.= '<h2>'.$titre.'</h2>'."\n";
			}
			// Affichage conditionnel de l'image personnelle (Visage, etc.)
			if(!empty($imgperso)) {
				$affichage.= '<img src="'.$imgperso.'" alt="" class="imgperso" />'."\n";
			}
			// Affichage conditionnel du numéro de téléphone
			if(!empty($telephone)) {
				$affichage.= '<p class="telephone">'.$telephone.'</p>'."\n";
			}
			// Affichage conditionnel du numéro de portable
			if(!empty($portable)) {
				$affichage.= '<p class="portable">'.$portable.'</p>'."\n";
			}
			// Affichage conditionnel de l'email
			if(!empty($email)) {
				$affichage.= '<p class="courriel"><a href="mailto:'.$email.'" target="_blank">'.$email.'</a></p>'."\n";
			}
			// Affichage conditionnel de la rue
			if(!empty($rue)) {
				$affichage.= '<p class="rue">'.$rue.'</p>'."\n";
			}
			// Affichage conditionnel du complément d'adresse (BP, n° d'appartement...)
			if(!empty($complement)) {
				$affichage.= '<p class="complement">'.$complement.'</p>'."\n";
			}
			// Affichage conditionnel du code postal et de la ville
			if(!empty($codepostal) && !empty($ville)) {
				$affichage.= '<p class="cpville">'.$codepostal.' '.$ville.'</p>'."\n";
			} else {
				// Affichage conditionnel du code postal
				if(!empty($codepostal)) {
					$affichage.= '<p class="codepostal">'.$codepostal.'</p>'."\n";
				}
				// Affichage conditionnel de la ville
				if(!empty($ville)) {
					$affichage.= '<p class="ville">'.$ville.'</p>'."\n";
				}
			}
			// Affichage conditionnel du pays d'origine
			if(!empty($pays)) {
				$affichage.= '<p class="pays">'.$pays.'</p>'."\n";
			}
		
		$affichage.= "</div>"."\n";
		
		// On affiche le résultat final
		echo $affichage;
		
		// Fin du widget
		echo $after_widget;
	}

	function update($new_instance, $old_instance) {
        $instance = $old_instance;
		$instance['image']		= $new_instance['image'];
		$instance['titre']		= esc_attr($new_instance['titre']);
		$instance['imgperso']	= esc_attr($new_instance['imgperso']);
		$instance['telephone']	= esc_attr($new_instance['telephone']);
		$instance['portable']	= esc_attr($new_instance['portable']);
		$instance['email']		= esc_attr($new_instance['email']);
		$instance['rue']		= esc_attr($new_instance['rue']);
		$instance['complement']	= esc_attr($new_instance['complement']);
		$instance['codepostal']	= esc_attr($new_instance['codepostal']);
		$instance['ville']		= esc_attr($new_instance['ville']);
		$instance['pays']		= esc_attr($new_instance['pays']);
		return $instance;
	}

	function form($instance) {
		// Valeurs par défaut (si le tableau instancié est vide)
		if(empty($instance)) {
			$defaut = array(
				"titre" => "Contact",
				"imgperso" => "",
				"telephone" => "",
				"portable" => "",
				"email" => "",
				"rue" => "",
				"complement" => "",
				"codepostal" => "",
				"ville" => "",
				"pays" => "",
				"image" => false
			);
			$instance = wp_parse_args($instance, $defaut);
		}
		
		// Formulaire personnalisé
	?>
        <p>
			<em>
				Entrez vos informations de contact...<br/>
				Chaque champ est optionnel et ne s'affichera que s'il est rempli !
			</em>
		</p>
        <div>
			<p>
				<label for="<?php echo $this->get_field_id('titre'); ?>"><strong>Titre</strong></label><br/>
				<input value="<?php echo $instance['titre']; ?>" name="<?php echo $this->get_field_name('titre'); ?>" id="<?php echo $this->get_field_id('titre'); ?>" type="text" style="width:100%;"/><br/>
			</p>
			<p>
				<label for="<?php echo $this->get_field_id('imgperso'); ?>"><strong>URL de l'image personnelle</strong></label><br/>
				<input value="<?php echo $instance['imgperso']; ?>" name="<?php echo $this->get_field_name('imgperso'); ?>" id="<?php echo $this->get_field_id('imgperso'); ?>" type="text" style="width:100%;"/><br/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('telephone'); ?>"><strong>Téléphone</strong></label><br/>
				<input value="<?php echo $instance['telephone']; ?>" name="<?php echo $this->get_field_name('telephone'); ?>" id="<?php echo $this->get_field_id('telephone'); ?>" type="text" style="width:100%;"/><br/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('portable'); ?>"><strong>Portable</strong></label><br/>
				<input value="<?php echo $instance['portable']; ?>" name="<?php echo $this->get_field_name('portable'); ?>" id="<?php echo $this->get_field_id('portable'); ?>" type="text" style="width:100%;"/><br/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('email'); ?>"><strong>Courriel</strong></label><br/>
				<input value="<?php echo $instance['email']; ?>" name="<?php echo $this->get_field_name('email'); ?>" id="<?php echo $this->get_field_id('email'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('rue'); ?>"><strong>Rue</strong></label><br/>
				<input value="<?php echo $instance['rue']; ?>" name="<?php echo $this->get_field_name('rue'); ?>" id="<?php echo $this->get_field_id('rue'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('complement'); ?>"><strong>Complément d'adresse</strong></label><br/>
				<input value="<?php echo $instance['complement']; ?>" name="<?php echo $this->get_field_name('complement'); ?>" id="<?php echo $this->get_field_id('complement'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('codepostal'); ?>"><strong>Code postal</strong></label><br/>
				<input value="<?php echo $instance['codepostal']; ?>" name="<?php echo $this->get_field_name('codepostal'); ?>" id="<?php echo $this->get_field_id('codepostal'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('ville'); ?>"><strong>Ville</strong></label><br/>
				<input value="<?php echo $instance['ville']; ?>" name="<?php echo $this->get_field_name('ville'); ?>" id="<?php echo $this->get_field_id('ville'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<label for="<?php echo $this->get_field_id('pays'); ?>"><strong>Pays</strong></label><br/>
				<input value="<?php echo $instance['pays']; ?>" name="<?php echo $this->get_field_name('pays'); ?>" id="<?php echo $this->get_field_id('pays'); ?>" type="text" style="width:100%;"/>
			</p>
            <p>
				<input name="<?php echo $this->get_field_name('image'); ?>" id="<?php echo $this->get_field_id('image'); ?>" type="checkbox" <?php if($instance['image'] == true) { echo 'checked="checked"'; } ?>/>&nbsp;
				<label for="<?php echo $this->get_field_id('image'); ?>"><strong>Afficher l'image d'entête ?</strong></label>
			</p>
        </div>
	<?php
	}
}
register_widget('WidgetPerso'); // Active le widget personnalisé
?>

Et maintenant le CSS de l’exemple, bien que celui-ci puisse être totalement modifié.

.contact-aside h2 {font-size:1.3em; text-align:center; margin:.6em 0;}
.contact-aside a {color:#242424;}
.contact-aside a:hover {text-decoration:none;}
.imgcontact {margin:0 auto; width:235px; display:block;}
.imgperso {margin:1em auto; width:100%; display:block; border:1px solid #242424;}
.telephone {background:url(telephone.png) no-repeat left .4em; padding-left:2em; line-height:1.8em;}
.portable {background:url(mobile.png) no-repeat left .4em; padding-left:2em; line-height:1.8em;}
.courriel {background:url(courriel.png) no-repeat left .5em; padding-left:2em; line-height:1.8em;}
.rue {background:url(adresse.png) no-repeat left .4em; padding-left:2em; line-height:1.8em;}
.complement {padding-left:2em; line-height:1.8em;}
.cpville {padding-left:2em; line-height:1.8em;}
.pays {padding-left:2em; line-height:1.8em;}
.codepostal {background:url(adresse.png) no-repeat left .5em; padding-left:2em; line-height:1.8em;}
.ville {background:url(adresse.png) no-repeat left .5em; padding-left:2em; line-height:1.8em;}

Paramètre du widget de contact WordPress

Ici, j’ai volontairement mis deux méthodes différentes pour les images, la première en « dur » pour l’image d’entête et la seconde modifiable pour l’image personnelle. Je conseille plutôt la seconde méthode, il vous suffit d’envoyer l’image dans la bibliothèque des médias puis de récupérer l’URL qui lui correspond pour l’héberger de manière sûre et surtout de pouvoir contrôler l’image.

J’espère que ce petit code vous aura plu, j’ai fait en sorte qu’il soit simple à comprendre donc ça devrait aller, n’hésitez pas si vous avez des suggestions...