0

私は 2 つの異なるアプローチでカスタム WordPress ループを作成してきましたが、どちらもWP_Queryオブジェクトの新しいインスタンスを作成する必要があります。通常、1 つのページに複数のループがあります。

これら 2 つのアプローチの違いと、それぞれを使用する正しいコンテキストを理解できません。

アプローチ 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すると、次のような 2 番目のアプローチでエラーが表示されます。

注意: is_singular が間違って呼び出されました。条件付きクエリ タグは、クエリが実行される前には機能しません。

私の質問は次のとおりです。

  • $original_query = $wp_query;いつアプローチを使用する必要がありますか?
  • 保存と復元の関連性は何$wp_queryですか?
  • 使用するとエラー メッセージが返されるのはなぜですか?
4

1 に答える 1

1

一部のコア機能 (ページネーション機能など) (これが要因であると思われる例を次に示します) は、値を想定し$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_single、設定解除されたグローバル オブジェクトにis_archive依存します。$wp_queryそのような場合に通知が表示されると思います。

参照に必要なほとんどすべては、 http://core.trac.wordpress.org/browser/trunk/wp-includes/query.phpおよびhttp://core.trac.wordpress.org/browser/trunk/wp-にあります。 includes/post-template.php

于 2013-02-14T02:07:36.563 に答える