테마 기본
필수 파일
style.css테마 메타데이터 헤더 + 스타일
index.php폴백 템플릿 (필수)
functions.php테마 설정, 훅, 인큐
screenshot.png테마 미리보기 (1200x900)
style.css 헤더
/* Theme Name: My Theme Theme URI: https://example.com Version: 1.0 Requires at least: 6.0 */
functions.php 설정
add_action('after_setup_theme', function() { add_theme_support('title-tag'); add_theme_support('post-thumbnails'); add_theme_support('html5', ['search-form', 'gallery']); register_nav_menus(['primary' => 'Main Nav']); });
템플릿 계층
페이지 템플릿
front-page.php정적 프론트 페이지
home.php블로그 포스트 인덱스
single.php단일 포스트
page.php단일 페이지
archive.php포스트 아카이브 (날짜, 카테고리)
category.php카테고리 아카이브
search.php검색 결과
404.php찾을 수 없음
index.php최종 폴백
템플릿 파트
get_header(); // header.php get_footer(); // footer.php get_sidebar(); // sidebar.php get_template_part('parts/card'); // parts/card.php get_template_part('parts/card', 'featured');
조회 순서 (단일 포스트)
1single-{post_type}-{slug}.php
2single-{post_type}.php
3single.php
4singular.php
5index.php
루프
표준 루프

템플릿 태그
the_title()포스트 제목 출력
the_content()포스트 콘텐츠 출력
the_excerpt()포스트 발췌문 출력
the_permalink()포스트 URL 출력
the_post_thumbnail()특성 이미지 출력
the_date()게시일 출력
the_author()작성자 이름 출력
the_category()카테고리 링크 출력
게터 (출력 없이 반환)
$title = get_the_title(); $url = get_permalink(); $id = get_the_ID(); $thumb = get_the_post_thumbnail_url(null, 'medium');
커스텀 포스트 타입
CPT 등록
add_action('init', function() { register_post_type('product', [ 'labels' => ['name' => 'Products', 'singular_name' => 'Product'], 'public' => true, 'has_archive' => true, 'supports' => ['title', 'editor', 'thumbnail'], ]); });
커스텀 분류
register_taxonomy('brand', 'product', [ 'labels' => ['name' => 'Brands'], 'hierarchical' => true, 'rewrite' => ['slug' => 'brand'], ]);
supports 옵션
title포스트 제목 필드
editor콘텐츠 에디터
thumbnail특성 이미지
excerpt발췌문 필드
custom-fields커스텀 필드 메타 박스
page-attributes메뉴 순서, 부모
revisions개정 이력
훅 및 필터
액션 (무언가 실행)
// Register a hook add_action('wp_head', 'my_analytics', 20); function my_analytics() { echo ''; }
필터 (데이터 수정)
// Modify the excerpt length add_filter('excerpt_length', fn() => 30); // Append text to every post add_filter('the_content', function($c) { return is_single() ? $c . '

Thanks for reading!

' : $c; });
주요 훅
initWP 초기화됨; 여기서 CPT 등록
wp_enqueue_scriptsCSS/JS 인큐
wp_head에 출력
wp_footer 앞에 출력
save_post포스트 저장 후
pre_get_posts실행 전 메인 쿼리 수정
the_content포스트 콘텐츠 출력 필터
the_title포스트 제목 출력 필터
WP_Query
커스텀 쿼리
$q = new WP_Query([ 'post_type' => 'product', 'posts_per_page' => 10, 'orderby' => 'date', 'order' => 'DESC', ]); while ($q->have_posts()) : $q->the_post(); the_title('

', '

'); endwhile; wp_reset_postdata();
일반적인 파라미터
post_typepost, page, 또는 커스텀 타입
posts_per_page결과 수 (-1이면 전체)
category_name카테고리 슬러그로 필터
tag태그 슬러그로 필터
s검색 키워드
meta_key / meta_value커스텀 필드로 필터
tax_query고급 분류 필터링
date_query날짜 범위로 필터
메인 쿼리 수정
add_action('pre_get_posts', function($q) { if (!is_admin() && $q->is_main_query() && is_home()) { $q->set('posts_per_page', 5); } });
REST API
내장 엔드포인트
/wp-json/wp/v2/posts포스트 목록 / 생성
/wp-json/wp/v2/posts/{id}포스트 조회 / 수정 / 삭제
/wp-json/wp/v2/pages페이지 엔드포인트
/wp-json/wp/v2/categories카테고리 엔드포인트
/wp-json/wp/v2/media미디어 라이브러리
/wp-json/wp/v2/users사용자 엔드포인트
커스텀 엔드포인트
add_action('rest_api_init', function() { register_rest_route('myplugin/v1', '/items', [ 'methods' => 'GET', 'callback' => fn($req) => new WP_REST_Response( get_posts(['post_type' => 'item', 'numberposts' => 20]) ), 'permission_callback' => '__return_true', ]); });
JavaScript에서 가져오기
const res = await fetch('/wp-json/wp/v2/posts?per_page=5'); const posts = await res.json(); posts.forEach(p => console.log(p.title.rendered));
함수
포스트 함수
get_posts($args)포스트 배열 가져오기
wp_insert_post($arr)포스트 생성 또는 업데이트
wp_delete_post($id)포스트를 휴지통 또는 삭제
get_post_meta($id, $key)커스텀 필드 값 가져오기
update_post_meta($id, $k, $v)커스텀 필드 값 설정
사용자 및 인증
wp_get_current_user()현재 로그인 사용자
is_user_logged_in()로그인 상태 확인
current_user_can($cap)권한 확인
wp_create_nonce($action)보안 nonce 생성
wp_verify_nonce($nonce, $a)nonce 검증
유틸리티 함수
esc_html($str)HTML 컨텍스트용 이스케이프
esc_attr($str)속성 컨텍스트용 이스케이프
esc_url($url)URL 새니타이즈
wp_kses_post($html)안전한 포스트 HTML만 허용
sanitize_text_field($s)태그 및 여분의 공백 제거
absint($val)절대 정수
인큐
스타일 및 스크립트 인큐
add_action('wp_enqueue_scripts', function() { wp_enqueue_style('theme-style', get_stylesheet_uri(), [], '1.0'); wp_enqueue_script('theme-js', get_theme_file_uri('/js/app.js'), ['jquery'], '1.0', true); });
인큐 함수
wp_enqueue_style($h, $src)CSS 등록 및 인큐
wp_enqueue_script($h, $src)JS 등록 및 인큐
wp_localize_script($h, $n, $d)PHP 데이터를 JS에 전달
wp_dequeue_style($handle)인큐된 스타일 제거
wp_dequeue_script($handle)인큐된 스크립트 제거
JavaScript에 데이터 전달
wp_enqueue_script('my-app', get_theme_file_uri('/js/app.js')); wp_localize_script('my-app', 'myData', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('my_action'), ]); // JS: console.log(myData.ajaxUrl)
자주 쓰는 패턴
커스텀 페이지 템플릿
AJAX 핸들러
add_action('wp_ajax_my_action', 'handle_my_action'); add_action('wp_ajax_nopriv_my_action', 'handle_my_action'); function handle_my_action() { check_ajax_referer('my_action', 'nonce'); wp_send_json_success(['msg' => 'OK']); }
숏코드
add_shortcode('greeting', function($atts) { $a = shortcode_atts(['name' => 'World'], $atts); return '

Hello, ' . esc_html($a['name']) . '!

'; }); // Usage: [greeting name="Zhi"]