워드프레스 – 루프 커스터마이징

일전에 워드프레스 루프에 대해 포스팅한 적이 있는데, 이는 테마를 만들 때 루프의 역할을 이해하고자 하는 목적이 있었다. 이번에는 루프가 어떻게 동작하는지 조금 더 자세히 들여다보고 루프를 입맛에 맞게 수정하는 방법들에 대해 살펴보도록 하겠다.

루프 기능을 커스터마이징하는 세 가지 방법

루프 기능은 크게 세 가지 방법으로 구현할 수 있는데 query_posts(), WP_Query(), get_posts()의 세 함수를 사용하는 방법이 있다. 사실 이 각각으로도 몇 개의 포스팅을 할 만큼 분량이 많기는 하지만 기본적인 수준에서 이해해보고자 하는 것이 이 글의 목적이다.

query_posts()

루프를 하나만 사용하고 반환되는 포스트들의 타입을 조정하고 싶다면 query_posts() 함수를 사용하면 된다. 이 함수를 사용하면 포스트 개수를 제한하거나 특정 카테고리/태그의 포스트를 제외하는 일을 할 수 있다.

참고 : http://codex.wordpress.org/Function_Reference/query_posts

WP_Query()

한 번에 여러 루프를 사용할 때 커스터마이징을 적용할 수 있는 강력한 도구이다. WP_Query()의 다른 인스턴스를 만들어서 루프를 여러 개로 만들고, 각각을 커스터마이징할 수 있다.

참고 : http://codex.wordpress.org/Class_Reference/WP_Query

get_posts()

get_posts() 함수는 테마의 어디서든 간단히 루프를 생성하는 방법이다. get_posts()는 query_posts()와 동일한 파라미터를 입력받아 사이드바, 푸터 등 어느 곳에서든 루프를 돌 수 있다.

query_posts()를 사용한 루프 커스터마이징

query_posts()는 워드프레스 루프에 대해 특정 카테고리를 제외하거나, 특정 카테고리만 포함하거나 하여 필터를 할 수 있고 개수를 제한할 수도 있다. query_post는 $query_string을 변경하므로, 사용후에는 wp_reset_query() 함수를 호출해서 쿼리를 복원해야 한다.

<?php
global $query_string;
$posts = query_posts($query_string.'&cat=-9'); // 특정 카테고리 빼기
if (have_posts()) : while (have_posts()) : the_posts();
...
endwhile; else:
...
endif;
wp_reset_query(); // 쿼리 복원
?>

조금 더 커스터마이징을 가미한다면 다음과 같은 형태도 가능하다.

$posts = query_posts($query_string.'&cat=-9,-8,-7&posts_per_page=3&order=ASC');

query_posts()를 사용할 때의 키는 원래의 쿼리를 전역변수인 $query_string에 저장해두고 루프가 끝난 후 리셋해준다는 점이다. 이는 쉽고 편리하기는 하지만 문제가 있다. query_posts()는 추가적인 DB 쿼리를 사용하기 때문에 is_page()나 is_single()과 같은 템플릿 태그에 영향을 끼칠 수 있다. 이러한 민감한 부분을 건드리지 않는 필요성은 WP_Query()를 통해 충족될 수 있다.

WP_Query()를 통한 커스터마이징

일단 코드부터 보자

<?php // Loop custominzed with WP_Query
$custom_query = new WP_Query('cat=-9');
while($custom_query->have_posts()) : $custom_query->the_post();
//...
endwhile;
wp_reset_postdata(); // 쿼리 복원
?>

이 방식은 전역 변수인 $query_string을 쓰지 않는다. 또한 커스터마이징하는 방법에서 여러 개의 조건은 &으로 묶을 수 있다.

이 방식의 위대함(?)은 WP_Query의 인스턴스를 원하는 만큼 만들어 그만큼의 루프를 하나의 페이지에서 여러 개 사용할 수 있다는 점이다.

다음 코드는 서로 다른 카테고리를 제외하면서 세 번의 루프를 도는 예를 보여준다.

<?php // Loop 1
$fist_query = new WP_Query('cat=-1');
while($fist_query->have_posts()) : $fist_query->the_post();
//...
endwhile;
wp_reset_postdata();

// Loop 2
$second_query = new WP_Query('cat=-2');
while($second_query->have_posts()) : $second_query->the_post();
//...
endwhile
wp_reset_postdata();

// Loop 3
$third_query = new WP_Query('cat=-3');
while($third_query->have_posts()) : $third_query->the_post();
//...
endwhile;
wp_reset_postdata();

WP_Query()를 사용하는 방법의 강점은 이 외에도 더 있지만, 조금 있다가 살펴보기로 한다.

get_posts()를 통해 루프를 커스터마이징하기

get_posts()는 멀티루프를 만드는 가장 안전한 방법이다. 이는 사실 while 구문을 사용하는 루프를 돌지 않고 별도의 쿼리를 만들어서 포스트를 구해온다.

<?php //additional loop via get_posts
global $post;
$args = array('category' => -9);
$custom_posts = get_query($args);
foreach ($custom_posts as $post) : setup_postdata($post);
//...
endforeach;
?>

이 때 다른 커스터마이징을 원한다면 다음과 같은 식으로 get_posts()에 넣을 파라미터를 변경할 수 있다.

$args = array('category'=>-7,-8,-9, 'numberposts'=>3, 'order'=>'ASC');

get_posts()에는 보다 많은 파라미터 들이 있는데 이들은 Codex에서 확인해보면 된다.