Widget d’affichage des derniers articles

Un des widgets WordPress les plus utilisés est celui qui permet l’affichage des N derniers articles du blog. S’il est très utile sur les pages internes, c’est à dire toutes sauf la page d’accueil, il ne fait que rajouter des liens redondants sur cette dernière.

Pour remédier à ce léger problème, je vous propose de réaliser votre propre widget, qui permettra de prendre en compte la page sur laquelle le visiteur se trouve. Pour cela, nous allons utiliser l’API de Widgets WordPress. En plus de l’aspect positif vis à vis du référencement naturel de votre blog (on évite ainsi des liens dupliqués puisque les derniers articles sont déjà visibles sur la homepage), ce sera l’occasion de vous familiariser avec la création de widgets WordPress.

Nous allons donc ajouter quelques lignes de code au fichier functions.php de votre thème. Pour comprendre plus facilement l’intérêt de chaque méthode, nous allons voir chacune d’elle en détail, mais les plus pressés peuvent aller directement à la fin de l’article pour récupérer le code complet.

Squelette

Commençons par créer une classe dérivée de WP_Widget :

class MesArticlesRecents extends WP_Widget {

	//Constructeur
	function MesArticlesRecents()
	{

	}

	//Affichage du widget
	function widget($args, $instance)
	{

	}

	//Mise à jour des paramètres du widget
	function update($new_instance, $old_instance)
	{

	}

	//Affichage des paramètres du widget dans l'admin
	function form($instance)
	{

	}
}

Pas grand chose à dire ici. Voyons la suite pour remplir nos méthodes.

Constructeur

Il s’agit ici d’appeler le constructeur de la classe parente WP_Widget :

function MesArticlesRecents()
{
	parent::WP_Widget(false, $name = 'Mes Articles Récents', array('name' => 'Mes Articles Récents', 'description' => 'Affichage des derniers articles du blog'));
}

On passe 3 paramètres au constructeur :

  • L’identifiant du widget, ici false. Laisser ce premier paramètre à false permet de forcer WordPress à définir automatiquement l’identifiant.
  • Le nom du widget.
  • Un tableau d’options permettant principalement de spécifier une description du widget, qui sera affichée dans l’interface d’administration.

Affichage

Cette méthode définit l’affichage du widget dans le front-end du blog : qu’est-ce qui sera affiché et comment.

function widget($args, $instance)
{
	if(!(is_home() || is_front_page())) {
		//Récupération des paramètres
		extract($args);
		$title = apply_filters('widget_title', $instance['title']);
		$nb_posts = $instance['nb_posts'];

		//Récupération des articles
		$lastposts = get_posts(array('numberposts'=>$nb_posts));

		//Affichage
		echo $before_widget;
		if ($title)
			echo $before_title . $title . $after_title;
		else
			echo $before_title . 'Articles Récents' . $after_title;

		echo '<ul>';
		foreach ( $lastposts as $post ) : setup_postdata($post); ?>
			<li><a href="<?php echo get_permalink($post->ID); ?>"><?php echo $post->post_title; ?></a></li>
		<?php endforeach;
		echo '</ul>';
		echo $after_widget;
	}
}

On commence par vérifier que l’on ne se trouve pas sur la page d’accueil. Si c’est le cas, on va alors récupérer les paramètres du widget (le titre à afficher et le nombre d’articles à afficher) puis les articles avec get_posts(). Par défaut, si aucune option n’est spécifiée, le titre sera Articles Récents et le widget affichera 5 articles (valeur par défaut de get_posts()).

On passe alors à l’affichage proprement dit : $before_widget, $after_widget, $before_title et $after_title sont des variables définies lors de l’enregistrement d’une sidebar. Ils correspondent au code HTML à insérer avant et après chaque widget (et son titre). En utilisant ces variables, on s’assure de respecter la mise en forme du thème, s’il est bien fait :p

Pour le reste, il s’agit simplement d’afficher pour chacun des derniers articles, son titre et un lien.

Mise à jour

Notre widget permet de prendre en compte deux paramètres : son titre affiché et le nombre d’articles à inclure. La méthode suivante permet de modifier ces deux paramètres :

function update($new_instance, $old_instance)
{
	$instance = $old_instance;

	//Récupération des paramètres envoyés
	$instance['title'] = strip_tags($new_instance['title']);
	$instance['nb_posts'] = $new_instance['nb_posts'];

	return $instance;
}

A chaque création ou mise à jour d’une instance de notre widget, la méthode enregistre dans la base de données du blog le titre et le nombre d’articles de l’instance.

Administration

Enfin, pour terminer notre classe, il faut permettre à l’administrateur du blog de renseigner ces deux paramètres. Pour cela, la méthode form() permet d’afficher le formulaire dans l’interface d’administration de WordPress :

function form($instance)
{
	$title = esc_attr($instance['title']);
	$nb_posts = esc_attr($instance['nb_posts']);
?>
	<p>
		<label for="<?php echo $this->get_field_id('title'); ?>">
			<?php echo 'Titre:'; ?>
			<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; ?>" />
		</label>
	</p>
	<p>
		<label for="<?php echo $this->get_field_id('nb_posts'); ?>">
			<?php echo 'Nombre d\'articles:'; ?>
			<input class="widefat" id="<?php echo $this->get_field_id('nb_posts'); ?>" name="<?php echo $this->get_field_name('nb_posts'); ?>" type="text" value="<?php echo $nb_posts; ?>" />
		</label>
	</p>
<?php
}

On commence par récupérer les valeurs actuelles des options, puis on les affiche dans les champs correspondants. Pour cela, deux méthodes de la classe WP_Widget vont être utilisée : get_field_id() pour récupérer l’ID du paramètre, et get_field_name() pour son nom.

Et voilà, nos quatre méthodes sont complètes, notre widget est presque terminé.

Enregistrement du Widget

Maintenant que notre classe est complète, reste le plus important : enregistrer le widget pour qu’il apparaisse dans l’interface d’administration de WordPress. Ceci se fait tout simplement à l’aide de la fonction register_widget() :

function dfr_register_widget() {
	register_widget( 'MesArticlesRecents' );
}
add_action('widgets_init', 'dfr_register_widget');

Vous devriez désormais trouver dans le menu Apparence > Widgets de votre blog un widget nommé Mes Articles Récents. A vous de le configurer et de le placer là où vous le souhaitez !

Si vous le souhaitez, vous pouvez modifier ce widget pour afficher autre chose que les N derniers articles, en utilisant à bon escient la fonction get_posts(). Pourquoi ne pas afficher par exemple les posts d’une catégorie en particulier, ou un type de post personnalisé ?

Le code complet :

class MesArticlesRecents extends WP_Widget {

	//Constructeur
	function MesArticlesRecents()
	{
		parent::WP_Widget(false, $name = 'Mes Articles Récents', array('name' => 'Mes Articles Récents', 'description' => 'Affichage des derniers articles du blog'));
	}

	//Affichage du widget
	function widget($args, $instance)
	{
		if(!(is_home() || is_front_page())) {
			//Récupération des paramètres
			extract($args);
			$title = apply_filters('widget_title', $instance['title']);
			$nb_posts = $instance['nb_posts'];
			
			//Récupération des articles
			$lastposts = get_posts(array('numberposts'=>$nb_posts));
		
			//Affichage
			echo $before_widget;
			if ($title)
				echo $before_title . $title . $after_title;
			else
				echo $before_title . 'Articles Récents' . $after_title;
				
			echo '<ul>';
			foreach ( $lastposts as $post ) : 
				setup_postdata($post); ?>
				<li><a href="<?php echo get_permalink($post->ID); ?>"><?php echo $post->post_title; ?></a></li>
			<?php endforeach;
			echo '</ul>';
			echo $after_widget;
		}
	}

	//Mise à jour des paramètres du widget
	function update($new_instance, $old_instance)
	{
		$instance = $old_instance;

		//Récupération des paramètres envoyés
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['nb_posts'] = $new_instance['nb_posts'];

		return $instance;
	}

	//Affichage des paramètres du widget dans l'admin
	function form($instance)
	{
		$title = esc_attr($instance['title']);
		$nb_posts = esc_attr($instance['nb_posts']);
	?>
		<p>
			<label for="<?php echo $this->get_field_id('title'); ?>">
				<?php echo 'Titre:'; ?>
				<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; ?>" />
			</label>
		</p>
		<p>
			<label for="<?php echo $this->get_field_id('nb_posts'); ?>">
				<?php echo 'Nombre d\'articles:'; ?>
				<input class="widefat" id="<?php echo $this->get_field_id('nb_posts'); ?>" name="<?php echo $this->get_field_name('nb_posts'); ?>" type="text" value="<?php echo $nb_posts; ?>" />
			</label>
		</p>
	<?php
	}
}

function dfr_register_widget() {
	register_widget( 'MesArticlesRecents' );
}
add_action('widgets_init', 'dfr_register_widget');

Evidemment, vous pouvez également vous servir de ce code pour créer tout un tas d’autres widgets WordPress !

Cet article a été publié dans WordPress par . Mettez-le en favori avec son permalien.
  • Le titre du widget n’apparait pas dans la partie administration. Pour corriger ce problème, il faut modifier

    function MesArticlesRecents()
    {
    parent::WP_Widget(false, $name = ‘Mes Articles Récents’, array(‘description’ => ‘Affichage des derniers articles du blog’));
    }

    par

    function MesArticlesRecents()
    {
    parent::WP_Widget(false, $name = ‘Mes Articles Récents’, array(‘name’ => ‘Articles recents’,’description’ => ‘Affichage des derniers articles du blog’));
    }

  • Merci pour cette correction Quentin, j’ai mis l’article à jour 🙂

  • Merci pour cet article !
    Un tout petit détail : l’accent sur « Récent » doit être codé HTML, sinon le titre ne s’affiche pas (chez-moi).

  • Sûrement un léger problème d’encodage 🙂

  • Je cherchais à faire un widget des derniers posts, donc ton article est très bien tombé pour moi.
    J’ai modifié légèrement le script pour afficher le titre, la date et un petit résumé de l’article.

    Merci pour cet article qui m’a grandement aidé !

  • brian

    bonjour et merci pour cet article. J’aimerai mettre sur ma page d’accueil,plusieurs widgets, les derniers articles par catégories,j’aimerai qu’en face du nom de la catégorie avoir l’image RSS et le lien RSS, ainsi les gens pourront rester informer sur une catégorie en particulier,c’est possible?
    merci

  • @brian: c’est tout à fait possible, mais ça n’est pas l’objet de cet article, qui est plutôt une sorte d’introduction pour vous encourager à essayer de le faire vous-même 😉

  • BOnjour,

    Merci pour ton article 🙂 !

    J’ai juste une question.

    Lorsque je suis ton tuto à la lettre j’ai une parse error –> Parse error: syntax error, unexpected T_CLASS… Aurais-tu une idée ? Merci d’avance !!!

  • Vérifie que tu as bien une version supérieure ou égale à 5 de PHP.
    Pour rappel, WordPress dans ses dernières versions requiert PHP 5.3.

  • darknote

    tout ça dans le fichier functions.php du thème?

  • @darknote: oui, tout ça dans le fichier functions.php
    Il est également possible d’inclure un fichier externe (comme n’importe quelle inclusion PHP) dans le fichier functions.php et de placer ce code dans ledit fichier annexe, mais le principe est le même 😉

  • Bonjour et merci de ton article,
    J’ai essayé de me lancer dans ce widget… malheureusement j’ai eu aussi droit à une parse error :
    syntax error, unexpected T_ENDFOREACH in /homez.527/lafaq/www/wp-content/themes/oxygen/functions.php on line 459
    n’étant pas spécialement compétent en endforeach et en php en général, j’ai supprimé tout le code que j’avais collé ; malheureusement même en l’ayant supprimé cette parse error subsiste, même si je n’ai pas de ligne 459 sur mon fichier functions.php ! Mon site entier plante, du coup…
    Please help ! Aurais-tu un début d’idée pour m’aider à solutionner ça ?
    D’avance un grand merci…

  • bon j’ai redéversé un fichier functions.php « purifié », donc j’ai au moins mon site, mais ça m’intéresse toujours de savoir pourquoi ça plante 😉

  • As-tu correctement copié le code source ?
    A priori pas de bug si c’est le cas.

  • rodolphe_

    J’ai trouvé dans votre article un excellent squelette pour construire un plugin. Un exemple concis et clair.
    Merci beaucoup!

  • Bonjour,

    Voulant passer à la vitesse supérieure dans mes prestations WordPress, je viens de voir cet article, excellent au passage.

    Malheureusement j’ai la même erreur que celle citée plus haut :
    syntax error, unexpected T_ENDFOREACH
    après avoir copier/coller pour en faire ma base de développement.

    Bon je vais retirer tout le code et reprendre à zéro, grâce à toi je vois maintenant comment faire, j’indique juste l’erreur pour corriger sur ce très bon tuto.

    Juste une petite question : quand on veut une autre page, comment la faire ? Il y a une API de WordPress qui permet de la reconnaitre par son identifiant ?

    Merci 🙂

  • C’est très étrange car je viens de retester et je n’ai pas du tout cette erreur.
    Essaie peut être de sauter une ligne après le « foreach ( $lastposts as $post ) : » (je viens de modifier le code de l’article en ce sens), mais ça devrait tout de même fonctionner.

    Par contre je n’ai pas compris la question ^^

  • Simplement, y a t-il moyen de sélectionner une autre page que la page d’accueil ?

    Je vais essayer ta modif, je reviendrai indiquer si ca fonctionne mieux.

    merci 🙂

  • Pour ce qui est des conditions, jette un oeil de ce côté : http://codex.wordpress.org/Conditional_Tags

  • Ok, trouvé, et comme beaucoup de bug, c’est très bête de ma part 🙂

    Il faut donc commencer par <?php
    Ensuite ajouter les commentaires qui vont bien pour identifier le widget (et pas l'inverse, c'est à dire le commentaire avant le final.

    Merci à toi pour cet exemple vraiment didactique.

  • darknote

    hello, on peut afficher les derniers articles d’une seule catégorie?
    Avec la fonction « image à la une » ?

  • @darknote: c’est tout à fait possible. Je t’invite à consulter la page de la fonction get_posts() sur le codex WordPress : http://codex.wordpress.org/Function_Reference/get_post

  • Ridolfi

    Bonjour,
    J’aurais voulu ajouter une classe pour modifier un widget « articles récents » de manière à ce qu’il ne renvoie que les articles d’une seule catégorie.
    En paramétrant votre script, peut-on y arriver, sachant que je devrai ajouter un filtre pour la catégorie à afficher?

    merci d’avance car je galère avec php

  • @Ridolfi: regarde du côté des paramètres de la fonction get_posts() : http://codex.wordpress.org/Function_Reference/get_posts 😉