Technote

개발 워크플로우 실무

연재 훅과 필터 제대로 쓰기 8부 중 4부

pre_get_posts — 가드 두 줄을 빠뜨리면 관리자까지 바뀝니다

이 훅은 모든 WP_Query 에 대해 돕니다. 메뉴 · 위젯 · 관리자 목록까지 전부 포함되므로, 판정 없이 조건을 넣으면 의도하지 않은 화면이 조용히 바뀝니다.

pre_get_posts 는 쿼리가 실행되기 직전에 그 조건을 고칠 수 있게 해 주는 훅입니다. 아카이브의 글 개수를 바꾸거나, 특정 조건의 글만 남기거나, 정렬을 바꾸는 일이 전부 여기서 됩니다. 템플릿에서 새 쿼리를 만들지 않고 메인 쿼리 자체를 고친다는 점이 핵심입니다 — 페이지네이션과 조건 태그가 그대로 살아 있기 때문입니다.

이 훅은 모든 쿼리에 대해 돕니다

가장 먼저 알아야 할 것은 이 훅이 메인 쿼리만이 아니라 모든 WP_Query 인스턴스에 대해 돈다는 사실입니다. 메뉴를 그릴 때도, 위젯이 최근 글을 뽑을 때도, 관리자 글 목록 화면을 그릴 때도 돕니다.

가드 없이 조건을 넣으면 함께 바뀌는 것들 — 아래 넷은 의도한 대상이 아니다

그래서 콜백의 첫 두 줄이 사실상 정해져 있습니다.

add_action( 'pre_get_posts', 'wper_book_archive' );

function wper_book_archive( $query ) {
	if ( is_admin() || ! $query->is_main_query() ) {
		return;
	}

	if ( ! $query->is_post_type_archive( 'book' ) ) {
		return;
	}

	$query->set( 'posts_per_page', 12 );
	$query->set( 'orderby', 'menu_order' );
}

판정에 전역 조건 태그가 아니라 $query-> 메서드를 쓰는 이유가 있습니다. 전역 태그는 언제나 메인 쿼리를 가리키므로, 지금 손보고 있는 그 쿼리가 아닌 다른 것에 대해 답할 수 있습니다.

덮어쓰지 말고 읽어서 더합니다

meta_querytax_query 를 그냥 set() 하면 이미 들어 있던 조건이 통째로 사라집니다. 다른 플러그인이 넣었을 수도 있고, 워드프레스가 그 화면을 위해 넣었을 수도 있습니다. 읽어서 더하는 형태로 씁니다.

$meta = (array) $query->get( 'meta_query' );

$meta[] = [
	'key'     => '_in_stock',
	'value'   => '1',
	'compare' => '=',
];

$query->set( 'meta_query', $meta );

남의 조건이 우리 화면을 비울 수도 있습니다

반대 방향의 사고도 있습니다. 이 저장소에서 커스텀 택소노미 아카이브 열 곳이 전부 0건으로 서 있던 적이 있습니다. 리라이트도 쿼리 대상도 정상이었는데, 실행된 SQL 에 우리가 넣지 않은 _thumbnail_id 조인이 들어 있었습니다.

부모 테마가 포트폴리오 목록에서 대표 이미지 없는 항목을 숨기려고 pre_get_posts 에 넣은 조건이었고, 그 판정이 $query->is_tax( $portfolio_taxonomies ) 였습니다. 이 사이트에는 포트폴리오 포스트 타입이 없어 그 배열이 빈 배열이 되는데, is_tax() 는 첫 인자가 비어 있으면 “택소노미를 가리지 않는다” 로 읽어 무조건 참을 돌려줍니다. 결과적으로 커스텀 택소노미 아카이브 전부가 포트폴리오 쿼리가 됐고, 우리 글은 썸네일을 코드로 그려 대표 이미지가 0장이므로 목록이 비었습니다.

화면은 200이고 제목도 필터도 멀쩡히 그려지고 빈 상태 문구까지 정상 출력됐습니다 — “아직 글이 없구나” 로 읽히지 고장으로 보이지 않습니다. 배운 것 두 가지입니다. 빈 배열과 빈 문자열을 같게 다루지 말 것, 그리고 목록이 이상하면 조건이 아니라 실제로 실행된 쿼리를 볼 것.

쿼리 디버깅 도구와 그 운영상의 주의는 개발 워크플로우 아카이브에 있고, 이런 지점을 포함한 전면 점검은 최적화 지원 사업에서 다룹니다.

다음 회차

다음 회차는 the_content 입니다. 같은 필터인데 우선순위 1에서 보는 것과 12에서 보는 것이 완전히 다른 문자열이고, “내 정규식이 아무것도 못 잡는다” 의 대부분이 여기서 나옵니다.

이 주제의 다른 글

노하우 목록으로

개발 워크플로우 실무

워드프레스를 GitHub 에 올릴 때의 .gitignore

워드프레스 저장소에서 커밋해야 할 것과 절대 커밋하면 안 되는 것의 경계는 명확합니다. wp-config.php 한 파일이 저장소에 들어가는 순간 DB 비밀번호와 인증 솔트가 통째로 유출됩니다.

개발자 · 운영 · 관리자 5분 읽기

개발 워크플로우 실무

취향 논쟁을 규칙 확인으로 바꾸는 디자인 리뷰

"좀 답답해 보인다" 는 반박할 수 없고 고칠 수도 없습니다. 간격 척도 밖의 값, 팔레트 밖의 색, 기준 미달 대비, 빠진 상태 — 네 항목만 규칙으로 바꿔도 리뷰의…

디자이너 4분 읽기

₩270,000 · 신청하기