問題描述

我正在使用 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;
}

最佳解決方案

説實話,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

當主查詢循環時,因為 before 循環開始,當前的帖子是-1,而循環結束後,當前的帖子將被重新設置為-1 。

所以,如果 in_the_loop()是真的,這意味着主查詢對象是循環的,這就是你在這種情況下需要的 (和 loop_start 上添加操作相同的結果,並且在 loop_end 上刪除,就像 @ialocin 寫的一樣; 事實上它的工作原理相同,得到了我的+1) 。

因為 in_the_loop()僅適用於主查詢,因此 @ ialocin 的方法的優點是當您要定位與主要查詢對象不同的查詢對象時。

次佳解決方案

這只是 @ 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' );
    }
}

第三種解決方案

您正在使用 is_main_query()。 global is_main_query() 函數返回 true,除非全局 $ wp_query 變量被重新定義。

從 the_content 篩選器中可以看出,您當前的 Loop 是否是主查詢,可能沒有 100%可靠的方式。內容過濾器只是過濾內容。它沒有任何形式的能力知道它被用於什麼循環。

相反,您應該在需要時添加過濾器,然後在不需要時將其刪除。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。