[워드프레스] 30. 자식테마 : 워드프레스 자식 테마로 안전하게 커스터마이징

워드프레스 해부 30편 - 워드프레스 자식 테마로 안전하게 커스터마이징

작성자

카테고리:

* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

(워드프레스 해부 ㉚) 자식테마

부모 테마를 직접 고치면, 테마가 업데이트될 때 2편에서 본 것처럼 수정이 통째로 날아간다. 그래서 커스터마이징은 자식 테마(child theme)에 한다. 부모의 기능은 다 물려받되, 내 변경만 자식에 얹는 구조다.

자식 테마는 폴더 하나 + 파일 두 개면 된다. style.css(부모를 가리키는 헤더)와 functions.php(부모 스타일 로드).

직접 해보기

워드프레스 자식 테마 만들기의 정석 세트다. 부모가 클래식 테마일 때 기준이고, 블록 테마는 아래에서 따로 다룬다.

/* wp-content/themes/mytheme-child/style.css */
/*
Theme Name:  My Theme Child
Theme URI:   https://example.com/
Description: 부모 테마 커스터마이징 전용 자식 테마
Author:      cozmo
Template:    twentytwentyfive      <-- 부모 테마 폴더명
Version:     1.0.0
Text Domain: mytheme-child
*/

헤더에서 필수는 Theme Name과 Template 두 줄뿐이다. 나머지는 테마 카드 표시용·캐시 버스팅(Version)·번역(Text Domain)용 부가 정보. 주석처럼 생겼지만 워드프레스는 이걸 파싱해 테마 정보로 쓴다.

<?php // wp-content/themes/mytheme-child/functions.php
add_action( 'wp_enqueue_scripts', function() {
    // 부모 스타일 (template = 부모 폴더)
    wp_enqueue_style( 'parent', get_template_directory_uri() . '/style.css' );
    // 자식 스타일 (stylesheet = 자식 폴더)
    wp_enqueue_style( 'child', get_stylesheet_directory_uri() . '/style.css',
        array( 'parent' ), wp_get_theme()->get( 'Version' ) );
} );

child theme functions.php에서 다들 한 번씩 막히는 게 두 URI 함수다. get_template_directory_uri()는 언제나 부모(Template) 폴더를, get_stylesheet_directory_uri()는 활성 테마 — 즉 자식 폴더를 가리킨다. 둘을 바꿔 쓰면 부모 스타일이 영영 안 온다. 셋째 인자 array( 'parent' )는 자식 스타일이 부모 뒤에 로드되게 하는 의존성 선언(16편)이다.

스타일 로드 순서 함정 — 자식 CSS가 부모보다 먼저 로드되면 같은 선택자를 부모가 도로 덮어쓴다. “고쳤는데 안 바뀌면” 로드 순서부터, 그다음 명시도를 의심하자.

Template: 줄이 부모 테마를 지정하는 핵심이다 — 이 값이 부모 테마의 폴더명과 한 글자라도 다르면 자식 테마가 아예 인식되지 않는다. 이제 자식 테마의 functions.php에 훅(13편)을 걸거나 템플릿을 덮어써도, 부모가 업데이트돼도 내 것은 유지된다.

활성화는 외모 → 테마에서 새로 뜬 카드를 누르면 끝이다(CLI는 wp theme activate mytheme-child). 직후 프런트가 부모와 똑같이 보이면 그게 성공 — 이 ‘변화 없음’이 상속이 제대로 걸렸다는 증거다.

✅ 확인 — 자식 테마를 활성화한 뒤 wp theme list --status=active가 자식 테마를 가리키고, 사이트가 부모와 똑같이 보이면 성공. 이제 여기에 안전하게 커스터마이징을 얹으면 된다.

템플릿 오버라이드 — 부모 파일을 복사해서 고친다

레이아웃 자체를 바꿀 땐 규칙 하나면 된다. 같은 이름의 템플릿이 자식에 있으면 자식 것을 쓴다. 템플릿 계층(15편)이 자식 폴더를 먼저 뒤지고 없으면 부모로 내려가기 때문이다. 실전은 부모의 single.php를 자식 폴더에 같은 이름으로 복사해 자식 쪽만 고치는 흐름 — 그 순간부터 글 상세는 자식 파일로 렌더링된다.

단, functions.php만은 예외다. 템플릿처럼 대체가 아니라 둘 다 로드된다 — 자식이 먼저, 부모가 나중. 부모 기능 위에 얹는 구조라서다.

블록 테마의 자식은 접근이 다르다

블록 테마의 자식은 사정이 좀 다르다. style.css의 Template 헤더로 부모를 지정하는 건 같지만, 스타일은 부모 스타일을 enqueue하는 트릭 대신 자식의 theme.json에 바꿀 값만 적으면 부모 것과 자동으로 병합된다. templates/·parts/ 폴더는 특정 템플릿을 덮어쓸 때만 만들고, 안 만들면 부모 것을 그대로 쓴다. 예컨대 링크 색 하나만 바꾸는 자식 theme.json은 이게 전부다.

// 자식 테마의 theme.json — 바꿀 값만 적는다
{
    "version": 3,
    "styles": {
        "elements": {
            "link": { "color": { "text": "#FF8000" } }
        }
    }
}
// 나머지 팔레트·폰트·템플릿은 부모 것과 자동 병합

enqueue 트릭도, 부모 파일 복사도 없다. 손이 훨씬 덜 간다.

템플릿 오버라이드 경로도 원리는 같다. 부모의 templates/single.html은 자식의 같은 경로에, 헤더·푸터 파트는 parts/ 아래 같은 이름으로 만들면 덮인다. 내용이 PHP가 아니라 블록 마크업일 뿐이다.

병합 우선순위는 theme.json 편(28편)의 층 그대로 — 코어 ← 부모 ← 자식 ← 사이트 편집기(DB), 뒤가 이긴다. 자식에 적었는데 안 먹으면 대부분 편집기에서 손댄 전역 스타일이 위에서 가리는 경우다. 편집기의 “스타일 초기화”로 비우면 자식 값이 드러난다.

덮어쓴 파일은 부모 업데이트를 안 받는다

자식 테마의 대표적인 함정이 이거다. 부모의 템플릿 파일을 자식에 복사해 덮어쓰면, 그 파일은 이후 부모가 아무리 업데이트돼도 자동으로 갱신되지 않는다. 그래서 부모를 업데이트한 뒤엔 내가 덮어쓴 파일들을 손으로 열어 변경사항을 반영해야 한다. 이 유지보수 부담을 줄이려면, 템플릿을 통째로 덮어쓰기보다 훅(필터·액션)으로 필요한 부분만 바꾸는 게 정석이다.

자식 테마가 지키는 것 / 못 지키는 것 — 자식 폴더 안의 내 파일은 부모가 몇 번 업데이트돼도 안 지워진다. 다만 부모가 훅 이름이나 템플릿 구조를 갈아엎으면 그 위에 짠 자식 코드는 깨질 수 있고, 사이트 편집기에서 DB로 저장한 수정은 애초에 자식 테마 소관이 아니다.

요즘은 자식 테마가 덜 필요하기도 하다

한 가지 덧붙이면, 블록 테마에선 사이트 편집기로 한 수정이 테마 파일이 아니라 DB에 저장되고 부모 업데이트에도 살아남는다. 그래서 ‘업데이트에 안전하려고’ 자식 테마를 만들던 옛 이유가 많이 약해졌다. 자식 테마가 지금도 유용한 건 커스터마이징을 코드로 버전관리하거나 배포 가능한 형태로 묶고 싶을 때다. 과정이 번거로우면 Create Block Theme 플러그인이 자식 테마 생성·theme.json 편집을 대신 처리해준다.

내 기준은 한 줄이다 — 편집기 수정은 DB에, 자식 테마는 파일에 산다. 색·타이포 수준이고 사이트가 하나면 편집기로 충분하다. 이 블로그도 Twenty Twenty-Five 위에서 자식 테마 없이 전역 스타일만 고쳐 굴린다. 반대로 PHP 훅, 여러 사이트 배포, Git 이력이 필요하면 파일 — 자식 테마다.

테마 모듈의 마지막은 재사용 레이아웃을 만드는 블록 패턴이다.

자주 묻는 질문 (FAQ)

자식 테마는 왜 쓰나요?

부모 테마를 직접 고치면 업데이트 때 사라집니다. 자식 테마에서 커스터마이징하면 부모를 업데이트해도 내 수정이 유지됩니다.

블록 테마도 자식 테마가 되나요?

됩니다. 다만 블록 테마는 사이트 편집기 수정이 DB에 저장돼 자식 테마가 예전만큼 필수는 아닙니다.

자식 테마의 functions.php는 부모 것을 대체하나요?

아니요. 템플릿 파일과 달리 functions.php는 둘 다 로드됩니다 — 자식이 먼저, 부모가 나중입니다. 부모 함수를 재정의하려면 부모가 function_exists()로 감싸둔 함수여야 합니다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다