web-dev-qa-db-fra.com

Requête: liste des publications décalées, sauf s'il s'agit d'une catégorie spécifique

Voici mon code:

<?php query_posts(array ('showposts' => '1', 'cat' => '-11'));
  if (have_posts()) : while (have_posts()) : the_post();
      get_template_part( 'content', 'archives' );
     endwhile;
  endif; ?>

<?php query_posts(array ('showposts' => '3', 'offset' => '1'));
  if (have_posts()) : while (have_posts()) : the_post();
      get_template_part( 'content', 'archives' );
     endwhile;
  endif; ?>

La première requête exclut une catégorie (contributions des utilisateurs au blog), de sorte que seul le dernier message de notre organisation sur notre blog est "collé".

La deuxième requête affiche actuellement les 3 derniers articles de toutes les catégories, avec un décalage de 1 pour empêcher l’affichage du message "collé", car c’est déjà le dernier.

Toutefois, si le message le plus récent se trouve dans la catégorie Contributions de l'utilisateur (nous publions parfois du contenu d'utilisateur plus tard dans la journée), il sera capturé par le "décalage" et ne sera pas affiché, et le message collé apparaîtra ensuite cette deuxième requête.

Existe-t-il une alternative à "offset" permettant d’exclure une catégorie de la règle?

TL; DR - Je souhaite que la deuxième requête exclue le résultat de la première requête.

1
tristanojbacon

Comme déjà indiqué, vous devriez ne jamais (j'insiste) utiliser query_posts pour créer des requêtes personnalisées.

Remarque: Cette fonction n'est pas destinée à être utilisée par des plugins ou des thèmes. Comme expliqué plus tard, il existe de meilleures options plus performantes pour modifier la requête principale. query_posts () est une façon trop simpliste et problématique de modifier la requête principale d'une page en la remplaçant par une nouvelle instance de la requête. Il est inefficace (ré-exécute les requêtes SQL) et échouera carrément dans certaines circonstances (particulièrement lorsqu'il s'agit de pagination de publications). Tout code WP moderne devrait utiliser des méthodes plus fiables, telles que l'utilisation du hook pre_get_posts, à cette fin.

Juste deux notes sur votre question et votre réponse (ce qui est bien une meilleure utilisation du code que votre question BTW :-))

  • showposts a été amorti en faveur de posts_per_page

  • JAMAIS oubliez de réinitialiser toute requête personnalisée. Comme décrit dans votre réponse, votre code devrait générer une sortie, car vous n'avez pas réinitialisé vos requêtes. Les requêtes personnalisées influencent toutes les requêtes qui la suivent si les données postérieures ne sont pas réinitialisées. Utilisez wp_reset_postdata() après chaque requête personnalisée

Voici comment votre code devrait ressembler

<?php $sticky = new WP_Query(array ('posts_per_page' => '1', 'cat' => '-11'));
if ($sticky->have_posts()) : 
    $stickyid = array(); 
while ($sticky->have_posts()) : $sticky->the_post(); 
$stickyid[] = $post->ID;
get_template_part( 'content', 'archives' );
endwhile; endif;
wp_reset_postdata();

$latestposts = new WP_Query(array ('posts_per_page' => '3', 'post__not_in' => $stickyid));
if ($latestposts->have_posts()) : 
    while ($latestposts->have_posts()) : $latestposts->the_post();
get_template_part( 'content', 'archives' );
endwhile; endif; 
wp_reset_postdata(); ?>
1
Pieter Goosen

EDIT: N'a pas résolu le problème, voir la note en bas. Après de nombreux essais et erreurs, j'ai réussi à résoudre le problème. Voici le code final (une adaptation de celui de la question):

<?php $sticky = new WP_Query(array ('showposts' => '1', 'cat' => '-11'));
if ($sticky->have_posts()) : 
    $stickyid = array(); 
while ($sticky->have_posts()) : $sticky->the_post(); 
$stickyid[] = $post->ID;
get_template_part( 'content', 'archives' );
endwhile; endif;

$latestposts = new WP_Query(array ('showposts' => '3', 'post__not_in' => $stickyid));
if ($latestposts->have_posts()) : 
    while ($latestposts->have_posts()) : $latestposts->the_post();
get_template_part( 'content', 'archives' );
endwhile; endif; ?>

Ce n'est peut-être pas la plus infime partie du code, mais cela a du sens pour moi! : S

EDIT: Il s'avère que ce n'est pas tout à fait correct. Pour une raison quelconque, les extraits de chaque message de la page utilisent l'extrait du message le plus récent (qu'il soit ou non collé). Toute suggestion quant à la manière de remédier à ce problème serait formidable!

1
tristanojbacon