추천 게시물을 얻기 위해 데이터베이스를 쿼리하려는 경우, 우리는 모두 새로운 WP_Query
를 만들고 루프를 통해 다음과 같이 해야 할 때라는 것을 알고 있습니다.
$featured_args = array(
'post__in' => get_option( 'sticky_posts' ),
'post_status' => 'publish',
'no_found_rows' => true
);
// Thre Featured posts query.
$featured = new WP_Query( $featured_args );
// Proceed only if published posts with thumbnails exist
if ( $featured->have_posts() ) {
while ( $featured->have_posts() ) {
$featured->the_post();
if ( has_post_thumbnail( $featured->post->ID ) ) {
// do stuff here
}
}
// Reset the post data
wp_reset_postdata();
}
Code language: PHP (php)
Awesome! 두 개의 쿼리, 충돌 없음 세상 모든 것이 옳습니다. wp_reset_postdata()
를 사용하는 것을 기억하고 있습니까? 😉 그렇지 않은 경우 모든 새로운 WP_Query
가 $post
전역을 방금 실행한 루프의 반복으로 대체하기 때문입니다. 재설정하지 않으면 메인 루프 쿼리에서 추천 게시물 쿼리의 $post
데이터로 끝날 수 있습니다.
query_posts()
를 기억하십니까? $wp_query
를 대체하고 $wp_the_query
를 다시 찾지 않습니다.
그렇다면 이제 추천 게시물 쿼리가 완료되고 추천 게시물을 모두 버린 후 메인 루프에서 추천 게시물을 제외하고 싶다면?
query_posts()
를 사용하고 기본 $wp_query
루프를 교체하려는 것이 합리적입니다. 맞습니까?
내 말은, 메인 루프 쿼리가 발생하기 전에 추천 게시물 쿼리를 실행하지 않았다면 제외할 대상을 어떻게 알겠습니까?
WP_Query
는 pre_get_posts
라는 작업으로 이를 매우 우아하게 처리하도록 설계되었습니다.
우리는 메인 루프, 추천 게시물, 제외할 query_posts()을 쿼리하는 대신 기본 쿼리를 미리 수정하고 원하지 않는 것을 제외하고 평소와 같이 추천 쿼리를 실행할 수 있습니다.
/**
* 홈 페이지 게시물을 필터링하고 기능을 갖춘 게시물 ID를 제거한다
* 포스트 배열을 얻기 전에 `pre_get_posts` 동작으로 쿼리의 매개변수를 변경합니다.
*
* @global array $featured_post_id
* @param WP_Query $query
* @return WP_Query Possibly modified WP_query
*/
function itheme2_home_posts( $query = false ) {
// 홈 페이지, 쿼리가 아닌경우, 메인 쿼리가 아닌경우, featured 포스트가 아님
if ( ! is_home() || !is_a( $query, 'WP_Query' ) || ! $query->is_main_query() || ! itheme2_featuring_posts() )
return;
// 메인 쿼라에서 featured 포스트를 제외
$query->set( 'post__not_in' itheme2_featuring_posts() );
// 'pre_get_posts'는 byref 작업입니다.
// 쿼리를 직접 수정하고 있습니다.
// 그렇기에 우리는 아무것도 반환하지 않습니다.
}
add_action( 'pre_get_posts', 'itheme2_home_posts' );
/**
* 게시물이있는 게시물이 우리의 조건을 충족하는지 확인하려면 테스트하십시오.
*
* 현재 조건은:
* - sticky posts
* - with featured thumbnails
*
* 루프의 결과를 일시적으로 저장하여 실행을 방지합니다.
* 모든 페이지로드에 대한 추가 쿼리. 결과는 POST ID의 배열입니다.
* 위의 결과를 일치시킵니다. 이것은 우리에게 특집을 통해 루프를 루프 할 수있는 빠른 방법을 제공합니다.
* 나중에 추가 시간을 쿼리 할 필요없이 나중에 다시 게시합니다.
*/
function itheme2_featuring_posts() {
if ( false === ( $featured_post_ids = get_transient( 'featured_post_ids' ) ) ) {
// sticky 게시물이있는 경우에만 계속하십시오
if ( get_option( 'sticky_posts' ) ) {
$featured_args = array(
'post__in' => get_option( 'sticky_posts' ),
'post_status' => 'publish',
'no_found_rows' => true
);
// featured 포스트 쿼리
$featured = new WP_Query( $featured_args );
// thumbnail이 있는 경우에만 계속 진행
if ( $featured->have_posts() ) {
while ( $featured->have_posts() ) {
$featured->the_post();
if ( has_post_thumbnail( $featured->post->ID ) ) {
$featured_post_ids[] = $featured->post->ID;
}
}
set_transient( 'featured_post_ids', $featured_post_ids );
}
}
// 포스트 ID를 캐시 또는 루프에서 반환하십시오.
return $featured_post_ids;
}
Code language: PHP (php)
다음 코드를 읽어 보자면
- 기본 쿼리를 필터링합니다.
- 홈페이지에 있는 경우에만 진행하십시오
- 쿼리가 엉망이 아닌 경우에만 진행하십시오
- 기본 쿼리를 필터링하려는 경우에만 진행하십시오
- 실제로 추천 게시물이 있는 경우에만 진행하십시오
- 추천 게시물? sticky 옵션을 확인해보자.
- 게시물이 있는 경우 게시물 쿼리
- (이 시점에서 WP_Query가 다시 실행되고
pre_get_posts
필터도 실행됩니다. 위의 검사 덕분에 추천 게시물에 대한 쿼리는 항목을 제외해야 해서 오염되지 않습니다. - 우리가 얻은 각 게시물 ID를 가져와 배열에 저장합니다.
- 페이지를 로드 할 떄마다 이 작업을 계속 수정하지 않도록 해당 배열을 캐시로 저장합니다.
- 추천 게시물을 끝내고 다시 기본 쿼리 필터로 돌아갑니다.
- 기본 쿼리에서 방금 얻은 게시물 ID를 제외합니다.
- 수정된 기본 쿼리 변수를 반환합니다.
- 나머지는 WordPress가 처리하도록 합니다.
잠재적 비용이 많이 드는 WP_Query
객체를 생성하지 않도록 약간의 로직을 스스로 설계할 수 있습니다.