the_content 및 is_main_query


15

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;
}

답변:


11

솔직히 말하면 기능 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()사실이라면 기본 쿼리 객체가 루핑되고 있음을 의미합니다.이 경우에는 필요합니다 ( @ialocin이 쓴 답변과 같이 액션을 추가하고 on loop_start을 제거 한 것과 동일한 결과입니다 loop_end. 실제로는 작동합니다) 같은 이유로 내 +1).

@ialocin의 접근 방식의 장점은 기본 쿼리 객체와 다른 쿼리 객체를 타겟팅하려는 경우입니다. in_the_loop() 기본 쿼리에서만 작동하기 입니다.


내 사이트 검색이나 온라인 검색에서이 문제가 발생하지 않았습니다. 작동하는 숨겨진 보석. 모든 솔루션은를 사용하므로 is_main_query아무도 이것을 철저히 테스트하지 않았다고 생각합니다. 귀하의 의견에 진심으로 감사드립니다
Pieter Goosen

1
@PieterGoosen 다행입니다. 그것은 아주 오래된 기능으로, 때가 is_main_query아닌 시대에서 바로옵니다 .
gmazzap

알다시피, 이것은 내가 놓친 곳입니다. 나는 오래된 타이머가 아닙니다 :-), Wordpress 3.3에 합류했습니다.
Pieter Goosen

2
@GM 당신의 답변에 이것을 추가 하시겠습니까? 이것은이 답변을 우연히 발견 할 수있는 다른 사람들에게 유용한 정보입니다. 나와 같은 대부분의 사람들은 댓글을 읽지 않습니다 :-)
Pieter Goosen

1
@PieterGoosen done :)
gmazzap

7

이것은 단지 @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' );
    }
}

이 내일을 테스트합니다. 자세한 설명 주셔서 감사합니다.
Pieter Goosen

언제나처럼 나의 기쁨 @PieterGoosen 서두르지 말고, 적어도 충분하지 않기 때문에 그렇게하십시오.
Nicolai

1
단축 코드가 the_content () 내에서 사용 중이고 단축 코드가 the_content ()를 호출하는 다른 쿼리를 시작하고 현재 포스트 객체를 재설정하고 루프가 계속되면 어떻게 될까요? 모든 필터가 적용됩니다. 여기에 아주 까다로운, 벨 in_the_loop () ... 그게 왜 난 항상 @Nicolai에 의해 접근으로 그들이 수행 한 빨리 고유의 필터를 제거하기 위해, 제안에 의해 저장되지 않습니다
조나스 Lundman을

5

당신이 사용하는 is_main_query()잘못 있습니다. 전역 $ wp_query 변수가 재정의되지 않은 경우 전역 is_main_query () 함수는 true를 반환합니다.

현재 필터가 현재 쿼리인지 여부를 the_content 필터 내부에서 100 % 신뢰할 수있는 방법이 없을 것입니다. 컨텐츠 필터는 컨텐츠 만 필터링합니다. 어떤 루프가 사용되고 있는지 알 수있는 기능이 없습니다.

대신 필요할 때 필터를 추가 한 다음 필요하지 않을 때는 제거해야합니다.


실제로 the_content필터를 사용 하여 기본 쿼리를 타겟팅 할 수있는 확실한 방법이 없다는 것은 실망스러운
Pieter Goosen

글쎄, 그건 정말 놀라운 일이 아닙니다. 다른 필터와 마찬가지로 사물 만 필터링합니다. 호출 될 때 주변 컨텍스트를 알 수 없습니다. 적절한 루프 내부에서 호출되지 않을 수도 있습니다. 말할 방법이 없습니다.
Otto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.