* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
(워드프레스 해부 ㉖) 메타박스
글 편집 화면에 “부제”, “평점” 같은 나만의 입력칸을 붙이고 싶을 때 쓰는 게 메타박스다. 이 편은 앞에서 배운 게 전부 모인다 — postmeta(9편)에 저장하고, nonce·sanitize(19편)로 지킨다.
직접 해보기
// 1) 메타박스 등록
add_action( 'add_meta_boxes', function() {
add_meta_box( 'my_subtitle', '부제', function( $post ) {
wp_nonce_field( 'save_subtitle', 'subtitle_nonce' ); // nonce
$v = esc_attr( get_post_meta( $post->ID, '_subtitle', true ) );
echo "<input name='subtitle' value='$v' style='width:100%'>";
}, 'post' );
} );
// 2) 저장 — nonce 검증 → sanitize → postmeta 저장
add_action( 'save_post', function( $id ) {
if ( ! isset($_POST['subtitle_nonce'])
|| ! wp_verify_nonce($_POST['subtitle_nonce'], 'save_subtitle') ) return;
update_post_meta( $id, '_subtitle', sanitize_text_field($_POST['subtitle'] ?? '') );
} );
✅ 확인 — 글 편집 화면에 “부제” 입력칸이 뜨고, 값을 넣어 저장한 뒤
wp post meta get [ID] _subtitle로 값이 나오면 성공._로 시작하는 키라 커스텀 필드 목록엔 안 뜨는데, 이건 9편에서 배운 “숨은 메타”다.
저장 처리 — nonce → 검증 → sanitize → 저장
메타박스에서 진짜 중요한 건 등록이 아니라 저장이다. save_post에서 nonce를 확인하고, 자동저장을 걸러내고, 권한을 검사한 뒤, 정제해서 update_post_meta로 넣는다. 이 순서를 지키지 않으면 보안 구멍이 되거나 값이 엉뚱하게 덮인다.
add_action( 'save_post', function ( $post_id ) {
// 1) nonce 확인 (위조 요청 차단)
if ( ! isset( $_POST['sub_nonce'] ) ||
! wp_verify_nonce( $_POST['sub_nonce'], 'save_sub' ) ) return;
// 2) 자동저장이면 건너뜀
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// 3) 권한 확인
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
// 4) 정제 후 저장
$v = sanitize_text_field( $_POST['subtitle'] ?? '' );
update_post_meta( $post_id, '_subtitle', $v );
} );
입력칸을 그리고, 값을 다시 채우기
렌더 콜백에선 두 가지를 한다. 위조 방지용 nonce 필드를 심고, 이미 저장된 값을 get_post_meta로 읽어 value에 채운다. 값을 다시 채워야 편집 화면을 다시 열었을 때 이전 입력이 그대로 보인다.
function my_subtitle_box( $post ) {
wp_nonce_field( 'save_sub', 'sub_nonce' );
$v = esc_attr( get_post_meta( $post->ID, '_subtitle', true ) );
echo '<input type="text" name="subtitle" value="' . $v . '" class="widefat">';
}
프런트에서 값 꺼내 쓰기
저장한 메타는 글 화면에서 get_post_meta로 읽어 출력한다. 출력할 땐 반드시 esc_html로 이스케이프한다(19편).
$sub = get_post_meta( get_the_ID(), '_subtitle', true );
if ( $sub ) echo '<p class="subtitle">' . esc_html( $sub ) . '</p>';
블록 에디터에선 다른 방식이 더 자연스럽다
고전 메타박스도 블록 에디터에서 동작은 한다. 다만 더 매끄러운 건 register_post_meta로 메타를 REST에 노출하고, 사이드바 패널(PluginDocumentSettingPanel)로 편집하는 방식이다. 헤드리스나 REST 연동까지 염두에 둔다면 이쪽이 낫다.
register_post_meta( 'post', '_subtitle', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function () { return current_user_can( 'edit_posts' ); },
) );
저장이 안 될 때 체크리스트
- nonce 필드를 렌더 콜백에 심었고, 저장에서 검증하는가.
- 자동저장을
DOING_AUTOSAVE로 걸러냈는가 (안 그러면 빈 값이 덮인다). current_user_can권한 검사를 통과하는가.meta_key철자가 등록·저장·조회에서 모두 같은가.
이 편은 postmeta(9편)와 보안(19편)이 한데 모이는 자리다. 두 개념을 이미 봤다면 메타박스는 그 조립일 뿐이다.
이걸로 확장 모듈 끝. 커스텀 콘텐츠·분류·숏코드·블록·설정·REST·메타박스까지, 워드프레스에 내 기능을 얹는 법을 다 봤다. 다음 모듈은 겉모습을 담당하는 테마의 구조로 넘어간다.
자주 묻는 질문 (FAQ)
메타박스가 뭔가요?
편집 화면에 추가하는 입력 상자입니다. add_meta_box로 등록하고, 저장 시 nonce 검증 후 postmeta에 값을 저장합니다.
블록 에디터에서도 메타박스가 되나요?
됩니다. 다만 블록 에디터에선 사이드바 패널(플러그인)로 만드는 방식이 더 자연스럽기도 합니다.

답글 남기기