WordPress : un plugin « Articles récents » optimisé

J’ai toujours été épaté par l’implémentation des plugins de base dans WordPress. CMS par excellence optimisé pour le référencement, WordPress se voit affublé de plugins dont les défauts sont si bénins qu’il serait dommage de ne pas les corriger ! Le plugin intégré Recent posts (Articles récents) est de ceux-ci… Voici un tout petit hack pour éviter que l’article en cours soit affiché dans la liste des derniers articles présentés à l’internaute.

Sans transitions, voici le code de notre petit plugin (basé sur celui intégré dans WordPress) :

<?php

/*
	Plugin Name: effiRecentPosts
	Plugin URI: http://www.effi10.com/recent-posts-plugin
	Description: Extends the default Recent Posts plugin, by simply filtering the current post of posts list
	Author: Cedric GIRARD
	Version: 1.0
	Author URI: http://www.effi10.com

	Copyright 2012  Cedric GIRARD  (email : contact@effi10.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

class WP_effiRecentPostsWidget extends WP_Widget {

	function __construct() {
		$widget_ops = array('classname' => 'effiwidget_recent_entries', 'description' => __( "The most recent posts on your site, excluding current post") );
		parent::__construct('recent-posts', __('effiRecent Posts'), $widget_ops);
		$this->alt_option_name = 'effiwidget_recent_entries';

		add_action( 'save_post', array(&$this, 'flush_widget_cache') );
		add_action( 'deleted_post', array(&$this, 'flush_widget_cache') );
		add_action( 'switch_theme', array(&$this, 'flush_widget_cache') );
	}

	function widget($args, $instance) {
		$cache = wp_cache_get('effiwidget_recent_posts', 'widget');

		if ( !is_array($cache) )
			$cache = array();

		if ( ! isset( $args['widget_id'] ) )
			$args['widget_id'] = $this->id;

		if ( isset( $cache[ $args['widget_id'] ] ) ) {
			echo $cache[ $args['widget_id'] ];
			return;
		}

		ob_start();
		extract($args);

		$title = apply_filters('widget_title', empty($instance['title']) ? __('Recent Posts') : $instance['title'], $instance, $this->id_base);
		if ( empty( $instance['number'] ) || ! $number = absint( $instance['number'] ) )
 			$number = 10;

		// Filtrage de la page en cours, le cas échéant
		$pCurrentID[]=0;	// On ajoute un ID bidon (afin que le tableau ne soit pas vide)
		if (is_single()) { $pCurrentID[]=get_the_ID(); }

		$r = new WP_Query(array('posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true, 'post__not_in' => $pCurrentID));
		if ($r->have_posts()) :
?>
		<?php echo $before_widget; ?>
		<?php if ( $title ) echo $before_title . $title . $after_title; ?>
		<ul>
		<?php  while ($r->have_posts()) : $r->the_post(); ?>
		<li><a href="<?php the_permalink() ?>" title="<?php echo esc_attr(get_the_title() ? get_the_title() : get_the_ID()); ?>"><?php if ( get_the_title() ) the_title(); else the_ID(); ?></a></li>
		<?php endwhile; ?>
		</ul>
		<?php echo $after_widget; ?>
<?php
		// Reset the global $the_post as this query will have stomped on it
		wp_reset_postdata();

		endif;

		$cache[$args['widget_id']] = ob_get_flush();
		wp_cache_set('effiwidget_recent_posts', $cache, 'widget');
	}

	function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['number'] = (int) $new_instance['number'];
		$this->flush_widget_cache();

		$alloptions = wp_cache_get( 'alloptions', 'options' );
		if ( isset($alloptions['effiwidget_recent_entries']) )
			delete_option('effiwidget_recent_entries');

		return $instance;
	}

	function flush_widget_cache() {
		wp_cache_delete('effiwidget_recent_posts', 'widget');
	}

	function form( $instance ) {
		$title = isset($instance['title']) ? esc_attr($instance['title']) : '';
		$number = isset($instance['number']) ? absint($instance['number']) : 5;
?>
		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></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('number'); ?>"><?php _e('Number of posts to show:'); ?></label>
		<input id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>
<?php
	}
}

function widget_initeffiRecentPosts()
{
	register_widget("WP_effiRecentPostsWidget");
}
add_action("widgets_init", "widget_initeffiRecentPosts");

?>

Et pour les fainéants, voici le lien pour le télécharger prêt à l’emploi : effiRecentPosts  😉

16 commentaires sur WordPress : un plugin « Articles récents » optimisé
  1. Daniel Roch Répondre

    Excellente initiative. Il est effectivement bizarre que WordPress cherche à afficher l’article en cours dans la liste des articles récents, car cela ne sert à rien ni pour le visiteur, ni pour le moteur de recherche.

    D’ailleurs, il faudrait aussi penser ce concept sur une page d’accueil, qui liste déjà les derniers articles : ce qui est redondant avec tout widget d’articles récents.

    • Cédric GIRARD Répondre

      Ahhh pour ça j’utilise Widget Logic Visual (variante « Ajax » de Widget Logic, parce que je suis fainéant 😉 ) : permet de choisir quels widgets on affiche sur quel(s) type(s) de pages…

      mais tu dois connaître !

  2. Antonin Répondre

    Merci pour le partage de la modif 😉

    À vrai dire, j’avais même pas remarqué que le plugin affichait l’article en cours de lecture : c’est que ça doit pas être si gênant que ça … mais bon c’est useless de proposer un article que tu es déjà en train de lire donc je vais modifier le plugin : merci !

    • Cédric GIRARD Répondre

      C’est vraiment une modif basique, mais bon comme je suis du genre perfectionniste 😉

  3. David Degliame Répondre

    Vous m’ennuyez tous là a faire du bon boulot ! :°)
    Je passe mon temps a répéter les mêmes commentaire : » ça tombe bien j’y ai pensé la semaine dernière …  »

    Bon et moi maintenant je poste quoi sur mon blog ?
    Enfin je dis cela mais le sujet mériterais bien plus qu’un simple plugin, sachant le nombre de microduplicate que l’on peut rencontrer sur ce genre de plateforme, que se soit pour les liens ou pour le contenu …
    Entre les menus les sides bar, les pages d’archives, les liens multiples au sein du même article ou encore dans les footers… Certains sites nous facilite la tache quand on dois regarder ce qui est en trop !

  4. Valentin Répondre

    Merci pour le plugin !
    Sans utiliser un autre plugin, on pouvais simplement ajouter « if( is_single()) { » ;p

  5. benjamin Répondre

    J’avais du aussi bricoler un script pour récupérer les 5 derniers articles de la base.
    Je vais tester ton code … merci pour le partage

  6. Gnomecorp Répondre

    Merci, je vais aller éditer quelques blogs. 😉

  7. rembelberge Répondre

    question
    si un psote est dans une catégorie, + section,
    + tag, cela fait du DC?
    y a t il un plug in pour remedier a ca?

  8. romain Répondre

    effectivement c’est un peu bizarre d’afficher l’article en cours…je vais tester le hack merci.

  9. romain Répondre

    Re,
    est ce qu’il est possible d’augmenter le nombre d’articles récents affichés dans un widget par exemple?

    • Cédric GIRARD Répondre

      C’est possible et paramétrable via le Widget offert par ce plugin 🙂

  10. romain Répondre

    merci pour la réponse, entre temps j’ai vu qu’on pouvait le modifier dans l’admin sur le widget et également dans le code si on veut encore plus augmenter la valeur.

  11. julia Répondre

    Merci pour ce hack, ça fait un moment que je cherchais une solution. Maintenant ce sera plus facile pour moi dans l’optimisation de ma page web.

  12. Gwen Répondre

    Salut, merci pour ce hack^^. Je me pose une autre question sur le duplicat content :
    Si nous décidons d’ affichez 3 articles en page d’accueil, comment faire pour que les article récents s’affiche à partir du 4 articles récents?

    • clem Répondre

      c’est possible mais il faut modifier le code en fonction, sinon y a plus simple pour éviter le duplicate, il suffit de mettre juste un extrait en page d’accueil (balise more)

Laisser un commentaire

Votre adresse email ne sera pas publiée. Merci de saisir votre nom ou pseudo (pas de pseudo SEO merci !), votre email et votre commentaire.