web-dev-qa-db-ja.com

the_contentとis_main_query

私はthe_contentフィルターで内容をフィルターしています。私の変更がカスタムクエリにも適用されることを除いて、すべてが完璧に機能します。ウィジェットがカスタムクエリを使用している場合、私の変更はサイドバーにも表示されます。

これに対処するために、is_main_query()を使用してメインクエリのみをターゲットにしていますが、機能していません。変更はすべてのクエリにそのまま適用されます。面白いのは、is_single()is_category()のような他のすべての条件付きチェックは、特定のページをターゲットにしている場合は動作します。ただし、is_main_query()を使用してもしなくても

私はここで何かが足りない。 the_contentフィルタのみを使用してメインクエリに変更を適用する方法

add_filter('the_content', 'custom_content');

function custom_content($content){

    if(is_main_query()){ // << THIS IS NOT WORKING
        // My custom content that I add to the_content()    
    }
    return $content;
}
13
Pieter Goosen

正直に言うと、 in_the_loop() という関数が探しているものです。

add_filter( 'the_content', 'custom_content' );

function custom_content( $content ) {
    if ( in_the_loop() ) {
        // My custom content that I add to the_content()    
    }
    return $content;
}

in_the_loopがすることは、現在の投稿の$wp_query(これはメインのクエリオブジェクトです)のグローバルかどうかをチェックすることです-1 < $current_post < $post_count

これは、メインのクエリがループしているときに発生します。ループの開始前に現在の投稿が-1になり、ループの終了後に現在の投稿が再び-1にリセットされるためです。

したがって、in_the_loop()がtrueの場合、メインのクエリオブジェクトがループしていることを意味します。これは、この場合に必要なことです(@ialocinの回答のように、loop_startのアクションの追加とloop_endの削除と同じ結果になります)。事実それは同じ理由で動作し、私の+1を得た。

in_the_loop()はメインクエリに対してのみ機能するので、@ ialocinのアプローチの利点は、メインとは異なるクエリオブジェクトをターゲットにしたい場合です。

11
gmazzap

これは@ Ottoの答えに対する単なる追加です。もう少しわかりやすくするためです。基本的に@Ottoが言っていることは、論理を逆にする必要があるということです。つまり、メインクエリを確実に決定できれば、フックをthe_contentフィルタに追加したり削除したりできます。

たとえば、メインクエリはpre_get_postsアクションで確実に認識されるので、これでうまくいきます。

function wpse162747_the_content_filter_callback( $content ) {
    return $content . 'with something appended';
}

add_action( 'pre_get_posts', 'wpse162747_pre_get_posts_callback' );
function wpse162747_pre_get_posts_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

不要になったときにフィルタを削除することになっているので、loop_endアクションはそれに適した場所であるべきだと考えています。その対応物としてloop_startを使用できます。これは次のようになります。

add_action( 'loop_start', 'wpse162747_loop_start_callback' );
function wpse162747_loop_start_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

add_action( 'loop_end', 'wpse162747_loop_end_callback' );
function wpse162747_loop_end_callback( $query ) {
    if ( $query->is_main_query() ) {
        remove_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}
7
Nicolai

is_main_query()を間違って使っています。グローバルな$ wp_query変数が再定義されていない限り、グローバルなis_main_query()関数はtrueを返します。

The_contentフィルタの中から、あなたが現在いるLoopがメインのクエリであるかどうかを知るための100%信頼できる方法はおそらくないでしょう。コンテンツフィルタはコンテンツをフィルタリングするだけです。どのループに使用されているのかを知ることはできません。

代わりに、必要に応じてフィルタを追加し、不要な場合は削除してください。

5
Otto