使用PRE_GET_POST过滤多循环归档中的一个循环

时间:2013-07-10 作者:Josh M

我有一个自定义的帖子类型归档(archive-rg\\u blog.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 // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>
编辑:我只是想澄清一下,这就是我想要做的。

///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
所以我需要在循环2之前添加过滤器,然后在循环3之前再次删除它。我尝试在适当的位置将过滤器添加到存档模板中,但循环2无法返回所有帖子。

编辑#2:下面是整个循环的运行情况。这是需要过滤的第二个循环。

<?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() ?>

2 个回复
SO网友:s_ha_dum

在需要的地方添加过滤器,然后remove it afterwards.

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
您还可以使您的操作自行删除:

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\');
您的代码,已重新组织:

// 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();
我还没有测试过,但我认为它会更好。希望我没有任何语法错误。

编辑:

我仔细查看了你的代码(而不是看“违抗”)并注意到了一些事情。

您的筛选器只会影响主查询,因此您需要在加载页面模板之前进行添加—可能在functions.php. 但我对这个问题的理解是,这个过滤器是用于第二个循环的。这意味着“主查询”检查是错误的get_post 通过ID,所以过滤器对那些人来说是无关紧要的因此,要筛选主查询,您需要在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\'); 
并且在其他任何地方都没有添加或删除操作。但我不确定这是你想要的。两个get_post 呼叫应不受影响。

SO网友:Michael Lewis

我建议检查一下is_post_type_archive 添加过滤器之前:

global $wp_query;
if ($wp_query->is_post_type_archive(\'rg_blog\')) {
    add_action(\'pre_get_posts\',\'blog_filter\');
}
这样,它就不会在每次加载页面时都运行。

尝试在第二次查询之前删除筛选器:

remove_action(\'pre_get_posts\', \'blog_filter\');

结束

相关推荐

页面不会使用LOOP或PRE_GET_POST显示在首页上

我改变了主题,以我认为“合适”的方式工作。在阅读了抄本并在这个网站上看到了一些东西之后。我从头开始。加载了2012主题。写了两页。主页和博客。我将主页设置为默认的2012年首页。php模板。然后在“设置->阅读”中,我将静态首页设置为主页,将贴子页面设置为博客。我知道这些帖子将从索引中删除。因此,在该文件中,我将自定义循环从博客类别和我的头版页面中拉出来。php文件我放置了一个自定义循环来获取页面。 $args = array( \'post_type\' => \'page\