web-dev-qa-db-fra.com

Utilisation de pre_get_posts pour filtrer une boucle dans une archive multiloop

J'ai une archive de type post personnalisé (archive-rg_blog.php) avec deux boucles. Une des boucles que je voudrais filtrer avec le code ci-dessous. Il ne s’agit que d’une boucle de base pour toutes les publications et je dois simplement la configurer pour renvoyer toutes les publications au lieu des publications personnalisées qu’elle renverrait par défaut.

L'autre boucle doit extraire le titre et le contenu d'une publication personnalisée spécifique. Le filtre ci-dessous semble également filtrer la deuxième boucle et ne renvoie rien du tout.

function blog_filter($query) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_post_type_archive('rg_blog')) {
      $query->set('post_type', 'post');
    }
  }
}
add_action('pre_get_posts','blog_filter');

Et c'est la boucle qui ne retourne rien:

<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>

Edit: Juste pour clarifier, c'est ce que j'essaie de faire.

///loop 1, queries a specific post
///loop 2, a normal loop filtered with pre_get_posts, which should return all posts.
///loop 3, also queries a specific post

J'ai donc besoin d'ajouter le filtre avant la boucle 2 et de le supprimer avant la boucle 3. J'ai essayé d'ajouter le filtre dans le modèle d'archive à l'emplacement approprié, mais la boucle 2 ne renvoie pas tous les articles.

Edit # 2: Voici la boucle entière en action. C'est la seconde boucle qui doit être filtrée.

<?php get_header(); ?>

<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>

<!-- Main Loop (All Posts)   -->
<?php function blog_filter($query) {
  if ( !is_admin() && $query->is_main_query()) {
    if ($query->is_post_type_archive('rg_blog')) {
      $query->set('post_type', 'post');
    }
  }
}
add_action('pre_get_posts','blog_filter');?>
<?php $post = $posts[0]; $c=0;?>
<?php if (have_posts()) : ?><?php while (have_posts()) : the_post(); ?>
<!--Featured Post-->
<?php $c++;
if( !$paged && $c == 1) :?>
<!--stuff-->
<!--Other Posts-->
<?php else :?>           
<!--the remaining posts-->          
<?php endif;?>
<?php endwhile; endif; ?>
<!-- The end of the loop   -->
<?php remove_action('pre_get_posts','blog_filter');?>

        <!--third loop, a repeat of loop 1-->  
<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>  
                <h1><?php echo $title;?></h1>
                <?php echo $queried_post->post_content;?>
<?php get_footer() ?>
1
Josh M

Ajoutez le filtre là où vous en avez besoin et supprimez-le ensuite .

add_action('pre_get_posts','blog_filter');
// your query; presumably WP_Query
// your first loop
remove_action('pre_get_posts','blog_filter');
// another query; presumably WP_Query
// your second loop

Vous pouvez également rendre votre action auto-extractible:

function blog_filter($query) {
  remove_action('pre_get_posts','blog_filter');
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_post_type_archive('rg_blog')) {
      $query->set('post_type', 'post');
    }
  }
}
add_action('pre_get_posts','blog_filter');

Votre code, réorganisé:

// define the function; can be here or functions.php
function blog_filter($query) {
  if ( !is_admin() && $query->is_main_query()) {
    if ($query->is_post_type_archive('rg_blog')) {
      $query->set('post_type', 'post');
    }
  }
}

get_header(); 

  // blog title and description query
  $post_id = 4606;

  // add the filter
  add_action('pre_get_posts','blog_filter'); 

  $queried_post = get_post($post_id);

  // remove the filter; the query is done
  remove_action('pre_get_posts','blog_filter'); 

  $title = $queried_post->post_title; ?>
  <h1><?php echo $title;?></h1><?php

  // Main Loop (All Posts)
  $post = $posts[0];
  $c=0;
  if (have_posts()) {
    while (have_posts()) {
      the_post(); 
      // Featured Post
      $c++;
      if( !$paged && $c == 1) {
        // stuff 
        // Other Posts
      } else {           
        // the remaining posts          
      }
    }
  }
  // The end of the loop
  // third loop, a repeat of loop 1

  // blog title and description query
  $post_id = 4606;
  $queried_post = get_post($post_id);
  $title = $queried_post->post_title; ?>  
  <h1><?php echo $title;?></h1><?php 
  echo $queried_post->post_content;
get_footer();

Je n'ai pas testé cela, mais je pense que cela fonctionnera mieux. J'espère n'avoir aucune erreur de syntaxe.

Modifier:

J'ai regardé de plus près votre code (tout en ne regardant pas "Defiance") et j'ai remarqué plusieurs choses.

  1. Votre filtre n'affectera que la requête principale; vous devrez donc l'ajouter avant le chargement du modèle de page - probablement dans functions.php. Mais ma compréhension de la question est que le filtre est destiné à une boucle secondaire. Cela voudrait dire que la vérification de la "requête principale" est fausse.
  2. Vous demandez des publications via get_post par ID, le filtre n'a donc aucune importance pour celles-ci.

Donc, pour filtrer cette requête principale, vous en avez besoin dans functions.php:

// define the function; can be here or functions.php
function blog_filter($query) {
  // remove the filter; the query is done
  remove_action('pre_get_posts','blog_filter');
  if ( !is_admin() && $query->is_main_query()) {
    if ($query->is_post_type_archive('rg_blog')) {
      $query->set('post_type', 'book');
    }
  }
}
add_action('pre_get_posts','blog_filter'); 

Et pas d'ajouter ou de supprimer des actions ailleurs. Je ne suis pas sûr que ce soit ce que vous voulez. Les deux appels get_post ne devraient pas être affectés.

2
s_ha_dum

Je suggère de vérifier le is_post_type_archive avant d'ajouter le filtre:

global $wp_query;
if ($wp_query->is_post_type_archive('rg_blog')) {
    add_action('pre_get_posts','blog_filter');
}

De cette façon, il ne fonctionnera pas à chaque chargement de page.


Essayez de supprimer le filtre avant la deuxième requête:

remove_action('pre_get_posts', 'blog_filter');
0
Michael Lewis