데브포일 홈
WordPress 자동화
Guest
STAGE 12 · Lv.59

커스텀 포스트 타입과 필드

register_post_type(), ACF/Meta Box 활용, 커스텀 필드와 필드 그룹, 관계 필드, 옵션 페이지를 배웁니다.

커스텀 포스트 타입(CPT)이란?

WordPress를 진정한 CMS로 확장하기

WordPress의 기본 포스트 타입은 "글(post)"과 "페이지(page)"입니다. 하지만 실제 프로젝트에서는 이 두 가지만으로는 다양한 콘텐츠를 체계적으로 관리할 수 없습니다. 커스텀 포스트 타입(Custom Post Type, CPT)을 사용하면 "포트폴리오", "상품", "이벤트", "팀원", "FAQ", "매물" 등 어떤 종류의 콘텐츠든 독립적인 콘텐츠 타입으로 관리할 수 있습니다.


CPT는 WordPress를 단순한 블로그 플랫폼에서 강력한 CMS(Content Management System)로 변환시키는 핵심 기능입니다. 부동산 사이트, 채용 사이트, 레스토랑 메뉴, 온라인 강좌, 디렉토리 사이트 등 거의 모든 종류의 웹 애플리케이션을 WordPress로 구현할 수 있게 해줍니다.


CPT가 필요한 실전 시나리오:

  • 부동산 사이트 - 매물(Property) CPT + 가격, 면적, 방 수, 주소 커스텀 필드
  • 레스토랑 - 메뉴 아이템(Menu Item) CPT + 가격, 재료, 알레르기 정보 필드
  • 학원/교육 - 강좌(Course) CPT + 강사, 일정, 수강료, 난이도 필드
  • 기업 사이트 - 팀원(Team) CPT, 서비스(Service) CPT, 사례연구(Case Study) CPT
  • 영화/도서 리뷰 - 영화(Movie) CPT + 감독, 장르, 개봉일, 평점 필드
  • 이벤트 사이트 - 이벤트(Event) CPT + 날짜, 장소, 가격, 참석자 수 필드
  • 포트폴리오 - 작업물(Portfolio) CPT + 클라이언트, 기술 스택, 갤러리 필드
  • 채용 사이트 - 채용공고(Job) CPT + 직무, 경력, 급여, 위치 필드
📦
20+
WordPress 내장 포스트 타입 수
🛠️
무한
생성 가능한 CPT 수
🏗️
ACF
가장 인기 있는 커스텀 필드 플러그인
🔗
REST API
CPT 데이터 외부 접근
📋
데이터 구조
설계
⚙️
CPT 등록
register_post_type
📝
커스텀 필드
ACF/Meta Box
🎨
템플릿
아카이브/싱글
🔍
WP_Query
데이터 조회

register_post_type() 모든 인자 상세

<?php
/**
 * ===== 커스텀 포스트 타입 등록 - 모든 인자 상세 해설 =====
 * functions.php 또는 커스텀 플러그인에 추가합니다.
 * 플러그인에서 등록하는 것을 강력히 권장합니다 (테마 변경 시 데이터 유지).
 */
add_action('init', 'register_property_post_type');

function register_property_post_type() {

    // ===== 라벨(Labels) 설정 =====
    // 관리자 화면에 표시되는 모든 텍스트를 지정합니다.
    $labels = array(
        'name'                  => '매물',              // 일반 이름 (복수)
        'singular_name'         => '매물',              // 단수 이름
        'menu_name'             => '매물 관리',          // 관리자 메뉴에 표시
        'name_admin_bar'        => '매물',              // 관리자 바의 "새로 추가"
        'add_new'               => '새 매물 등록',       // 추가 버튼 텍스트
        'add_new_item'          => '새 매물 등록',       // 추가 페이지 제목
        'new_item'              => '새 매물',            // 새 항목
        'edit_item'             => '매물 편집',          // 편집 페이지 제목
        'view_item'             => '매물 보기',          // 보기 링크
        'view_items'            => '매물 목록 보기',     // 목록 보기 링크
        'all_items'             => '모든 매물',          // 하위 메뉴 "모든 항목"
        'search_items'          => '매물 검색',          // 검색 버튼
        'parent_item_colon'     => '상위 매물:',         // 계층형일 때 상위 항목
        'not_found'             => '등록된 매물이 없습니다',  // 검색 결과 없음
        'not_found_in_trash'    => '휴지통에 매물이 없습니다', // 휴지통 비었음
        'featured_image'        => '매물 대표 이미지',    // 대표 이미지 레이블
        'set_featured_image'    => '대표 이미지 설정',
        'remove_featured_image' => '대표 이미지 제거',
        'use_featured_image'    => '대표 이미지로 사용',
        'archives'              => '매물 아카이브',       // 아카이브 레이블
        'insert_into_item'      => '매물에 삽입',
        'uploaded_to_this_item' => '이 매물에 업로드됨',
        'filter_items_list'     => '매물 목록 필터',
        'items_list_navigation' => '매물 목록 네비게이션',
        'items_list'            => '매물 목록',
    );

    // ===== 포스트 타입 인수(Arguments) 설정 =====
    $args = array(
        'labels'             => $labels,

        // --- 공개 및 접근 설정 ---
        'public'             => true,       // 프론트엔드와 관리자 모두에서 접근 가능
        'publicly_queryable' => true,       // URL로 조회 가능 (?post_type=property 또는 /property/slug)
        'show_ui'            => true,       // 관리자 UI(편집 화면) 표시
        'show_in_menu'       => true,       // 관리자 좌측 메뉴에 표시 (true/false/문자열)
        'show_in_nav_menus'  => true,       // 외모 → 메뉴에서 선택 가능
        'show_in_admin_bar'  => true,       // 관리자 바의 "새로 추가"에 표시
        'show_in_rest'       => true,       // REST API 노출 (Gutenberg 블록 에디터 필수!)
        'rest_base'          => 'properties', // REST API 엔드포인트 이름 (/wp-json/wp/v2/properties)
        'rest_namespace'     => 'wp/v2',    // REST API 네임스페이스

        // --- URL 설정 ---
        'query_var'          => true,       // URL 쿼리 변수 사용 (?property=slug)
        'rewrite'            => array(
            'slug'       => 'property',     // URL 슬러그 (example.com/property/매물이름)
            'with_front' => false,          // 퍼머링크 앞부분(/blog/) 포함 여부
            'pages'      => true,           // 페이지네이션 지원 (/property/page/2/)
            'feeds'      => true,           // RSS 피드 지원 (/property/feed/)
        ),
        // 'rewrite' => false,              // URL 접근 비활성화 (비공개 CPT)

        // --- 기능 설정 ---
        'capability_type'    => 'post',     // 권한 유형 ('post', 'page', 또는 커스텀)
        // 'capability_type' => array('property', 'properties'),  // 커스텀 권한
        // 'map_meta_cap'    => true,       // 메타 권한 매핑 (커스텀 권한 사용 시)

        'has_archive'        => true,       // 아카이브 페이지 활성 (example.com/property/)
        // 'has_archive'     => 'properties', // 커스텀 아카이브 슬러그

        'hierarchical'       => false,      // false = 글처럼 (평면), true = 페이지처럼 (계층)
        'exclude_from_search' => false,     // 검색 결과에서 제외 여부
        'can_export'         => true,       // 내보내기 도구에 포함 여부
        'delete_with_user'   => false,      // 사용자 삭제 시 콘텐츠도 삭제할지

        // --- 관리자 메뉴 설정 ---
        'menu_position'      => 5,          // 메뉴 위치 (5=글 아래, 20=페이지 아래, 25=댓글 아래)
        'menu_icon'          => 'dashicons-building', // 메뉴 아이콘 (dashicons 또는 SVG base64)
        // 'menu_icon'       => 'data:image/svg+xml;base64,...', // 커스텀 SVG 아이콘

        // --- 지원 기능(Supports) ---
        'supports'           => array(
            'title',           // 제목 필드
            'editor',          // 본문 에디터 (Gutenberg 또는 Classic)
            'thumbnail',       // 대표 이미지
            'excerpt',         // 요약(발췌)
            'custom-fields',   // 기본 커스텀 필드 (메타 박스)
            'revisions',       // 수정 내역 (되돌리기)
            'author',          // 작성자 선택
            'page-attributes', // 페이지 속성 (순서, 부모 - hierarchical일 때)
            // 'comments',     // 댓글 (필요한 경우만)
            // 'trackbacks',   // 트랙백 (거의 사용 안 함)
            // 'post-formats', // 포스트 형식 (비디오, 갤러리 등)
        ),

        // --- 분류체계(Taxonomy) 연결 ---
        'taxonomies'         => array('property_type', 'property_location'),

        // --- 템플릿 ---
        'template'           => array(),    // 기본 블록 에디터 템플릿
        'template_lock'      => false,      // 템플릿 잠금 (false, 'all', 'insert')
    );

    register_post_type('property', $args);
}
?>
        
CPT 이름 규칙
register_post_type()의 첫 번째 인자(포스트 타입 이름)는 최대 20자, 소문자, 밑줄(_)만 사용하세요. 하이픈(-)은 사용하지 마세요. WordPress 내장 포스트 타입(post, page, attachment, revision, nav_menu_item)과 중복되지 않아야 합니다. 접두사를 붙여 충돌을 방지하는 것이 좋습니다(예: mysite_property). show_in_rest를 true로 설정해야 Gutenberg 블록 에디터가 작동합니다.
🔒
여기까지는 미리보기입니다
커스텀 포스트 타입과 필드
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)