Tout savoir sur WordPress

Personnaliser les requêtes avec WP_Query

Ce guide passe en revue la class WP_Query de WordPress. Nous allons voir comment personnaliser nos requêtes grâce à cette class.

Si vous voulez afficher sur votre index.php, single.php ou un autre fichier un contenu différent de ce que fait la boucle WordPress de base, il suffit d’utiliser WP_Query.

WP_Query est une class qui permet de créer des requêtes personnalisées pour récupérer vos posts selon des critères définis via le paramètre du constructeur de cette classe. Pour utiliser cette requête il faut la stocker dans une variable et utiliser cet objet dans la boucle WordPress :

<?php
$query = new WP_Query($args); 
if($query->have_posts()) : while($query->have_posts()) : $query->the_post();
?>
 // Votre contenu ici
<?php endwhile;endif; ?>

Cette class est paramétrable à souhait, beaucoup de possibilité s’offre à vous, voici quelques exemples d’utilisation.

Récupérer la totalité des articles

<?php $query = new WP_Query(array('post_type' => 'post')) ; ?>

Récupérer tous les articles et toutes les pages

<?php $query = new WP_Query(array('post_type' => array('post', 'page'))); ?>

Récupérer les 4 derniers articles

<?php $query = new WP_Query(array('post_type' => 'post', 'posts_per_page' => 4)) ; ?>

Récupérer les 4 derniers articles d’une ou plusieurs catégories

<?php $query = new WP_Query(array('posts_per_page' => 4, 'category_name' => 'slug-de-votre-categorie')) ; ?>

Vous pouvez aussi utiliser un ou plusieurs ID ou même le slug des catégories à récupérer.

$query = new WP_Query('posts_per_page' => 4, 'cat=2,6,17,38');
$query = new WP_Query('posts_per_page' => 4, 'category_name=actualites,film,musique');

Récupérer le custom post type « film » trié par titre dans l’ordre décroissant

<?php $query = new WP_Query(array('post_type' => 'film', 'orderby' => 'title', 'order' => 'DESC')); ?>

Récupérer la totalité des posts qui n’ont pas l’ID indiqué

<?php $query = new WP_Query(array('post__not_in' => array(2, 5, 12, 14, 20))); ?>

Récupérer la totalité des posts qui ont l’ID indiqué

<?php $query = new WP_Query(array('post__in' => array(2, 5, 12, 14, 20 ))); ?>

Pour plus d’informations et d’avantages de personnalisation sur la class WP_Query rendez-vous sur la page du codex.

Cet article a été publié il y a 1647 jours - Il n'est peut être plus à jour !

Article écrit par Rtransat

27 Commentaires

Laisser un commentaire

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

  1. Merci pour ce petit tuto.
    J’ai une petite question..
    Logiquement si je fais ‘post_type’ => array(‘actualites’, ‘flashinfos’) » je devrais seulement avoir les articles de ces 2 customs pt ? Or j’ai tout (même les pages)..Alors que si je fais une requête avec juste « flashinfos » ou une avec juste « actualites », j’ai bien les bons articles…

    As-tu une idée d’où ca pourrait venir?

    Merci

  2. @quentin
    C’est tout à fait ce qu’il faut faire.
    Dans ton objet WP_Query tu passe ton tableau comme tu l’as dis si bien ;) et ensuite quand tu fais la loop WordPress tu utilise bien sûr ton objet.

    Perso j’utilise des CPT dans des boucles WordPress et ça fonctionne parfaitement :)

    (Fais attention d’avoir le bon nom de ton custom post type, quand tu crée ton CTP via la méthode assure toi d’avoir en premier paramètre le nom de ton custom post type qui sera utilisé dans les boucles)

    register_post_type(‘ctp1’, $argsCPT1);
    register_post_type(‘ctp2’, $argsCPT2);

    Exemple :

    array(‘cpt1’, ‘cpt2’)
    );
    $ctp = new WP_Query($args);
    if($ctp->have_posts()): while($ctp->have_posts()): $ctp->the_post();
    the_title();
    endwhile; endif;

  3. RTRANSAT :
    Justement, quand je passe le tableau que j’ai indiqué, il me ressort tous les articles et les pages du sites..et non les articles des 2 cpts.

    J’ai vérifié les « id » que j’ai indiqué lors de la création des cpts, il n’y a pas d’erreur, d’ailleurs ils marchent un par un..

    D’autre part, j’ai découvert que je faisais ‘post_type’=>’post’, j’avais également le même resultat, il ressort tous les articles de tous les cpt et toutes les pages..
    Je sais pas si c’est le cas chez vous?

    J’ai fais pas mal de recherches, et il y a plusieurs tutos pour selectionner les contenus de plusieurs ctp, donc ca doit être faisable..

    David, une solution que j’ai trouvé c’est de contourner le problème et d’utiliser get_posts, mais je continue de chercher…

    Si quelqu’un d’autre a une piste, je suis preneur :)

  4. Bonsoir , je vais essayé d’afficher tout mes catégories dans une page , donc j’ai mis dans ma page (template) , le code
    4, ‘category_name’ => ‘slug-de-votre-categorie’)) ; ?> mais sa fonction pas . svp aidez moi

  5. bonjour,
    on met où wp_reset_query() après endif ?
    et slug-de-votre-categorie, on le remplace par le nom de la catégorie voulue ?

    Désolé mais ce qui peut vous paraitre évidement, me donne un sentiment d’incertitude.
    et si on veut avoir « image à la une » on met quel code et où ?

    Merci

  6. Bonjour,

    Je voudrais utiliser les requêtes de la base de données d’un thème vers un autre thème sachant que les 2 thèmes sont identiques avec les mêmes widgets.

    Simplement j’ai un problème vis à vis de la connection. Par défaut, le thème se connecte à la base de données par l’intermèdiaire des chaines de connexion dans le fichier wp-config.php

    $events = New WP_Query($args);

    Comment puis récupérer les données de WP_Query($args); avec une nouvelle connexion du type :

    $link=mysql_connect($db_host, $db_user, $db_pass);
    if (!$link) {
        die('error : ' . mysql_error());
    }
    
    $bd_seleccionada = mysql_select_db($db_name, $link);
    if (!$bd_seleccionada) {
        die ('error : ' . mysql_error());
    }
    

    J’espère que quelqu’un pourra m’aider.

    Merci,

  7. Bonjour. Avez-vous une idée de la manière de procéder pour avoir une boucle proposant des articles en relations avec la page en cours ?

    Ceux-ci seraient hierarchisés par affinité de tags (jusque là j’y arrive), puis complété si besoin avec des articles de la même class si le tag ne contient pas assez d’article…

    Car je sais faire des boucles différentes, mais limiter tout cela pour un maximum de 12 articles… là, je n’y arrive pas.

  8. Oui merci, j’avais déjà renseigné ce paramètre.

    Là où ça coince, c’est ma tentative de combiner à la fois une série d’article liée a un tag (je sais faire aussi) ET les dernier article du site ET de limiter le tout à 12 articles. Je n’arrive pas à configurer sans qu’un paramètre écrase l’autre…

    Par exemple, sur l’article disponible à partir de mon profil, à la suite des 2 articles en lien par le tag (pour l’instant), j’aimerai avoir aussi les derniers articles publiés pour compléter jusqu’à 12.

  9. @Olivier C: il suffit de suivre l’exemple de la partie « Récupérer les 4 derniers articles d’une ou plusieurs catégories », mais d’adapter les paramètres aux tags et non aux catégories.

  10. Comment récupérer le nombre d’articles par tag et pour une période précise (entre telle date et telle date par exemple, ou sur les 30 derniers jours) ?

  11. @Christophe: Pour manipuler les dates, je te laisse regarder du côté des Date Query. C’est apparu depuis la version 3.7 de WordPress et ça répondra à ton besoin.

  12. Merci. Je suis effectivement tombé là-dessus, mais le site de mon client n’est pas en 3.7, du coup ça ne fonctionnait pas. Je ne peux pas update pour le moment car des plugins essentiels au site ne sont pas encore compatibles avec 3.7. J’ai procédé autrement, ça fonctionne mais du coup je n’ai que les posts du mois souhaité (novembre dans mon exemple). Je n’arrive pas à avoir entre telle date et telle date:

    $tags = array('tagA', 'tagB', 'tagC');
    
    foreach ($tags as $tag) {
    	$args = array(
    		'year'  => 2013,
    		'monthnum' => 11,
    		'tag' => $tag
    	);
    
    	$query = new WP_Query( $args );
    	
    	if($query){
    		echo $tag . ';' . $query->found_posts . '';
    	} else {
    		echo 'error ' . $tag . '';
    	}
    }
  13. Bonjour,

    Merci pour cet article.
    Je n’arrive pas à faire fonctionner WP_Query avec un search parameter (‘s’ => ‘miel’)

    Qu’est ce que tu sais comment l’intégrer correctement dans une WP_Query? Dois-je faire une modification dans le function.php?

    Merci d’avance.
    Cdt,Gwen

  14. salut, ton article m’a bien aidé, il resume bien l’énorme page sur les queries du wordpress codex :)
    Peut etre que tu peux me conseiller sur un petit problème que j’arrive pas à résoudre :

    J’ai une home page avec plusieurs wp_queries (j’utilise ACF Advanced Custom Fields) dynamiques : l’utilisateur ajoute autant de blocks de posts qu’il souhaite via les custom fields (ACF) de la page d’accueil dans le back office.

    Chaque blocs de posts doit etre présenté avec un slideshow jquery unique pour chaque bloc (pour pas que les posts défilent tous ensemble lorsque l’on slide). ils doivent donc avoir un id unique.

    Mon problème c’est que je ne connais pas de methode pour ajouter un id unique a chaque wp_query. par exemple : wp-query-1, wp_query-2, wp_query-2, etc… Que l’id de chaque query soit numéroté automatiquement tant qu’il y a une nouvelle query a ajouter.

    C’est pas très clair je pense, mais si tu vois ce que je veux dire et que tu as une idée, je suis preneur :)

    merci !

  15. @hedi: Arff, je ne comprends pas vraiment la demande et le besoin. Pour répondre à la question : non, il n’est pas possible de « numéroter » de WP_Query()

  16. C’est un peu tard, mais mieux vaut tard que jamais. Tu peux numéroter, une fois dans la boucle white(), tu créer une variable ex: $i=0; que tu incréments $i++, se qui te donnera un ID unique suivant la position de la boucle.

  17. Bonjour,
    Cet article est très intéressant mais comment faire une requête a partir d’un formulaire de recherche ?
    Je m’explique.
    Je souhaite que mes utilisateurs avec un formulaire de recherche avec deux ou trois selectbox puissent récupérer des custum post et les afficher.
    Comment faire?
    Cordialement

  18. Est-il possible avec WP_Query d’avoir la catégorie en cours plutôt qu’indiquer le slug de la catégorie (afin de l’afficher dans single.php) ?

    Afin d’avoir ceci :
    4, ‘category_name’ => ‘CATEGORIE-EN-COURS’)) ; ?>

    Merci pour l’astuce !