WordPress:不同的WP_Query用法:哪个是正确的,在哪个上下文?

时间:2013-02-14 01:03:07

标签: wordpress loops

我一直在使用两种不同的方法创建自定义WordPress循环,这两种方法都涉及创建WP_Query对象的新实例。我通常在一个页面上有多个循环。

我不明白这两种方法有何不同,哪种方法可以正确使用。

方法1:http://codex.wordpress.org/Class_Reference/WP_Query

$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
        // output
    endwhile;
endif;

wp_reset_postdata();

方法2:http://codex.wordpress.org/Function_Reference/wp_reset_postdata

$original_query = $wp_query;
$wp_query = null;

$wp_query = new WP_Query( $args );
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        // output
    endwhile;
endif;

$wp_query = null;
$wp_query = $original_query;
wp_reset_postdata();

两者似乎产生相同的结果,但是当我打开WP_DEBUG时,我看到第二种方法的错误,例如:

  

注意:is_singular被错误地调用。在运行查询之前,条件查询标记不起作用。

我的问题是这些:

  • 何时应该使用$original_query = $wp_query;方法?
  • 存储和恢复$wp_query的相关性是什么?
  • 为什么在我使用它时会返回错误消息?

1 个答案:

答案 0 :(得分:1)

一些核心功能 - 例如一些分页功能(here is an example where this seems to have been a factor) - 假设$wp_query值。如果未设置,则这些功能不起作用。您可以通过保存原始$wp_query,运行自定义循环以及放回$wp_query来解决此问题。我认为这很少是最好的方法,如果你认为你需要这样做,你应该使用pre_get_posts或其他过滤器来改变主查询本身而不是制作一个新的查询。我不会发誓绝对没有合适的情况,但我认为通常有更好的方法。

我尝试时你的代码不会触发任何通知,但如果你做了类似的事情,它会:

$original_query = $wp_query;
$wp_query = null;
if (is_single()) {
  echo 'single post';
}
$wp_query = new WP_Query( array('posts_per_page' => 5) );

is_singleis_archive等功能依赖于未设置的全局$wp_query对象。我希望它是在你看到通知的情况下。

您需要参考的大部分内容都在http://core.trac.wordpress.org/browser/trunk/wp-includes/query.phphttp://core.trac.wordpress.org/browser/trunk/wp-includes/post-template.php