워드프레스 테마 만들기 – 4

네, 좋습니다! 1편, 2편, 3편을 거치며 워드프레스 테마의 기본 구조, 작동 원리, 그리고 필수적인 기능 구현 방법들을 상세히 알아보았다.

이제 워드프레스 테마 만들기 여정을 마무리하며, 실전에서 테마의 완성도를 높이고 사용자에게 더 나은 경험을 제공하기 위한 추가적인 고려사항과 모범 사례들을 집중적으로 다루어 보겠다.

마지막 4편에서는 테마의 품질을 결정짓는 중요한 요소들, 즉 접근성, 다국어 지원, 보안, 그리고 효율적인 코드 작성 습관에 대해 깊이 있게 이야기하며, 테마 개발 여정을 깔끔하게 마무리해 보겠다.

지금까지 워드프레스 테마의 뼈대를 세우고(index.php, style.css 등), 콘텐츠를 담는 방법(The Loop, 템플릿 태그), 구조를 짜는 법(header.php, footer.php, sidebar.php, 템플릿 파트), 그리고 사용자가 일부 설정을 변경할 수 있게 하는 법(테마 커스터마이저)까지 차근차근 살펴보았다.

이제 만든 테마를 좀 더 많은 사람이 불편함 없이 사용하고, 안전하며, 나중에 관리하기 쉽게 만드는 단계로 나아가 보겠다.

1. 접근성(Accessibility)

웹사이트 접근성은 장애를 가진 사람이나 고령자 등 신체적, 기술적 조건과 관계없이 모든 사용자가 웹사이트의 정보에 접근하고 기능을 이용할 수 있도록 하는 것이다.

좋은 워드프레스 테마는 시작부터 접근성을 고려해야 한다. 워드프레스 자체는 접근성을 염두에 두고 설계되었지만, 테마 개발자가 어떻게 코드를 작성하느냐에 따라 접근성 수준이 크게 달라진다.

테마 개발 시 고려해야 할 기본적인 접근성 요소들이다.

  • 의미론적 HTML 마크업: <header>, <nav>, <main>, <aside>, <footer>, <article>, <section> 등 HTML5 의미론적 태그를 올바르게 사용하여 웹페이지의 구조를 명확하게 한다. 스크린 리더 사용자가 페이지 구조를 쉽게 파악할 수 있게 돕는다.
  • 키보드 내비게이션: 마우스 없이 키보드만으로도 웹사이트의 모든 링크, 버튼, 폼 필드 등에 접근하고 조작할 수 있도록 한다. :focus CSS 셀렉터를 사용하여 현재 활성화된 요소(키보드 포커스 위치)를 시각적으로 명확하게 표시해야 한다. 워드프레스의 기본 메뉴(wp_nav_menu) 등은 키보드 접근성을 어느 정도 지원한다.
  • 이미지 대체 텍스트(Alt Text): 모든 중요한 이미지에는 alt 속성을 사용하여 이미지가 무엇을 나타내는지 설명하는 대체 텍스트를 제공한다. 시각 장애인이 스크린 리더를 통해 이미지의 내용을 이해할 수 있다. 워드프레스의 the_post_thumbnail() 함수 등은 이미지의 alt 속성을 자동으로 채워주는 기능을 제공한다.
  • 색상 대비: 텍스트와 배경색의 대비가 충분하여 저시력 사용자도 내용을 읽기 쉽게 해야 한다. WCAG(웹 콘텐츠 접근성 지침) 기준에 맞는 색상 조합을 사용한다.
  • ARIA 속성 활용: 필요에 따라 ARIA(Accessible Rich Internet Applications) 속성(예: role, aria-label, aria-hidden)을 사용하여 동적인 콘텐츠나 복잡한 UI 요소의 역할을 스크린 리더에 정확하게 전달한다.
  • 워드프레스 내장 기능 활용: 워드프레스 코어에서 제공하는 접근성 관련 함수나 기능들(예: language_attributes(), body_class(), wp_skip_link())을 적극적으로 활용한다.

예를 들어, header.php 파일에서 접근성을 위한 스킵 링크를 추가하는 것은 좋은 습관이다.

<body <?php body_class(); ?>>
    <div id="page" class="site">
        <!-- 접근성을 위한 스킵 링크: 키보드 사용자가 반복적인 탐색 링크를 건너뛰고 바로 콘텐츠로 이동하게 한다 -->
        <a class="skip-link screen-reader-text" href="#content"><?php esc_html_e( 'Skip to content', 'my-first-theme' ); ?></a>

        <header id="masthead" class="site-header">
            <!-- ... 헤더 내용 ... -->
        </header>

        <div id="content" class="site-content"> <!-- 스킵 링크의 대상이 되는 메인 콘텐츠 시작점 -->
            <div id="primary" class="content-area">
                <main id="main" class="site-main">
                    <!-- ... 메인 콘텐츠 (루프 등) ... -->
                </main>
            </div>
            <?php get_sidebar(); ?>
        </div>
        <!-- ... 푸터 내용 ... -->
    </div>
    <?php wp_footer(); ?>
</body>

screen-reader-text 클래스는 시각적으로는 숨기지만 스크린 리더는 읽을 수 있도록 하는 워드프레스 표준 클래스이다. 접근성은 선택 사항이 아니라 필수 사항이며, 테마 개발 초기 단계부터 꾸준히 신경 써야 한다.

2. 다국어 지원(Internationalization – i18n)

만든 테마를 한국어뿐만 아니라 다양한 언어로 사용하고 싶다면 다국어 지원(i18n)을 해야 한다.

테마에 하드코딩된 모든 텍스트 문구(예: “더 읽어보기”, “댓글 달기”, “검색 결과”)를 다른 언어로 번역 가능하게 만드는 과정이다.

워드프레스에서 다국어 지원은 주로 다음 함수들을 사용하여 이루어진다.

  • __(): 번역 가능한 텍스트를 반환한다. (echo 하지 않는다.)
  • _e(): 번역 가능한 텍스트를 즉시 출력(echo)한다.
  • esc_html__(), esc_html_e(): HTML 이스케이프 처리와 함께 번역을 지원한다. 보안상 더 안전하게 사용한다.
  • esc_attr__(), esc_attr_e(): HTML 속성 값으로 사용될 텍스트를 이스케이프 처리와 함께 번역을 지원한다.
  • load_theme_textdomain(): 테마 번역 파일(.mo)을 로드한다. functions.phpafter_setup_theme 액션 훅 안에서 사용한다.

예제 코드 (템플릿 파일 또는 functions.php):

// functions.php 의 setup 함수 안에서
load_theme_textdomain( 'my-first-theme', get_template_directory() . '/languages' ); // 'my-first-theme'는 테마의 고유 텍스트 도메인, /languages 폴더에서 번역 파일 찾음

// 템플릿 파일 안에서 텍스트 표시 (index.php, archive.php 등)
?>
<a href="<?php the_permalink(); ?>" rel="bookmark">
    <?php
    /* translators: %s: Name of current post. Only visible to screen readers */
    printf( // 변수(%s)가 포함된 문자열 번역 시 printf 사용
        wp_kses( // HTML 태그가 포함될 수 있는 문자열 안전하게 처리
            __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'my-first-theme' ), // 번역 대상 문자열과 텍스트 도메인
            array( 'span' => array( 'class' => array() ) ) // 허용할 HTML 태그와 속성
        ),
        wp_kses_post( get_the_title() ) // 번역될 변수 내용 (글 제목), 안전하게 처리
    );
    ?>
</a>

<?php // 다른 예: 단순 텍스트 출력
_e( 'Search Results for:', 'my-first-theme' ); // "Search Results for:" 문자열 출력 및 번역 지원
?>
<span><?php echo esc_html( get_search_query() ); ?></span>

<?php // 다른 예: 버튼 텍스트
?>
<button type="submit"><?php esc_html_e( 'Search', 'my-first-theme' ); ?></button>

텍스트 도메인(Text Domain)은 테마의 고유 식별자 역할을 한다. style.css 주석 부분과 load_theme_textdomain() 함수, 그리고 __(), _e() 등의 번역 함수 호출 시 반드시 일관되게 사용해야 한다. 일반적으로 테마 폴더 이름과 동일하게 지정한다.

모든 사용자에게 표시되는 텍스트 문구들을 위 함수들로 감싸고 텍스트 도메인을 지정해 두면, Poedit과 같은 번역 도구를 사용하여 .pot (Portable Object Template) 파일을 생성하고, 이 파일을 번역하여 각 언어별 .po, .mo 파일을 만든 후 테마의 /languages 폴더에 넣어 테마를 번역할 수 있게 된다.

3. 보안과 코딩 표준

테마 코드는 웹사이트의 보안과 성능에 직접적인 영향을 미친다.

취약한 테마는 사이트 해킹의 경로가 될 수 있고, 비효율적인 코드는 성능 저하를 유발할 수 있다. 보안과 코딩 표준을 지키는 것은 매우 중요하다.

보안 관련 모범 사례:

  • 입력값 검증(Validation) 및 소독(Sanitization): 사용자가 입력하거나 외부에서 들어오는 모든 데이터는 신뢰할 수 없다고 가정하고, 사용하기 전에 반드시 유효성을 검증하고 소독해야 한다.
    • 검증(Validation): 데이터가 예상한 형식(예: 이메일 주소 형식, 숫자 범위)인지 확인한다.
    • 소독(Sanitization): 유해할 수 있는 문자나 코드 조각(HTML, JavaScript 등)을 제거하거나 변환한다.
      주요 소독 함수: sanitize_text_field(), sanitize_email(), sanitize_url(), absint() (정수), sanitize_html_class(), sanitize_hex_color() 등.
      이 작업은 주로 설정 값을 저장하거나(예: 테마 커스터마이저에서 입력받은 값) 사용자 입력 데이터를 처리할 때 functions.php에서 이루어진다.
  • 출력값 이스케이프 처리(Escaping): 데이터베이스에서 가져오거나 변수를 통해 출력되는 모든 데이터는 화면에 표시하기 전에 반드시 이스케이프 처리해야 한다. 이를 통해 악성 스크립트 삽입(XSS 공격)을 방지할 수 있다.
    주요 이스케이프 함수: esc_html() (일반 HTML 콘텐츠), esc_attr() (HTML 속성 값), esc_url() (URL), wp_kses() (제한된 HTML 태그 허용), wp_kses_post() (포스트 콘텐츠에 허용되는 태그 허용).
    이 작업은 주로 템플릿 파일에서 echoprintf 등으로 데이터를 출력하기 직전에 이루어진다.

예제 코드 (소독 및 이스케이프):

// functions.php 또는 설정 저장 시 (소독 예)
$my_option_value = isset( $_POST['my_custom_field'] ) ? sanitize_text_field( $_POST['my_custom_field'] ) : ''; // POST로 받은 값 소독

// 테마 커스터마이저 설정 시 sanitize_callback 지정 (앞선 3편 예제 참고)
// $wp_customize->add_setting( 'my_setting', array( 'sanitize_callback' => 'sanitize_text_field' ) );

// 템플릿 파일 출력 시 (이스케이프 예)
<h1 class="page-title"><?php echo esc_html( get_the_title() ); ?></h1> <!-- 글 제목 이스케이프 -->
<a href="<?php echo esc_url( get_permalink() ); ?>">더 읽어보기</a> <!-- URL 이스케이프 -->
<div class="<?php echo esc_attr( $css_class_variable ); ?>">...</div> <!-- CSS 클래스 이름 이스케이프 -->

<p>작성일: <?php echo esc_html( get_the_date() ); ?></p> <!-- 날짜 이스케이프 -->
  • 직접 파일 접근 방지: 테마의 PHP 파일 중 functions.php, inc/ 폴더 내 파일, template-parts/ 폴더 내 파일 등은 웹 브라우저에서 직접 URL로 접근하여 실행되면 안 된다. 파일 상단에 다음과 같은 코드를 추가하여 워드프레스 환경에서만 로드되도록 한다.
<?php
/**
 * 이 파일은 워드프레스 환경에서만 로드되어야 합니다.
 */

if ( ! defined( 'ABSPATH' ) ) { // ABSPATH는 워드프레스 설치 경로 상수를 의미하며, 워드프레스 로드 시에만 정의된다.
    exit; // Directly access denied.
}

// ... 파일의 나머지 코드 ...
  • 워드프레스 코딩 표준: 워드프레스 공식 코딩 표준(PHP, CSS, HTML, JavaScript)을 따르면 코드의 일관성과 가독성이 높아져 다른 개발자가 코드를 이해하고 유지보수하기 쉬워진다.

성능 관련 모범 사례:

  • wp_enqueue_scripts 활용: 스타일과 스크립트를 로드할 때 항상 wp_enqueue_style()wp_enqueue_script() 함수를 사용하여 중복 로드를 피하고 의존성을 관리한다.
  • 필요한 스크립트/스타일만 로드: 모든 페이지에서 필요하지 않은 스크립트나 스타일은 특정 페이지(예: 댓글 창이 있는 페이지에서만 comment-reply 스크립트 로드)에서만 조건부로 로드하도록 코드를 작성한다.
  • 이미지 최적화: 웹사이트에 사용되는 이미지 크기를 적절하게 조정하고 압축하여 파일 크기를 줄인다. 워드프레스의 미디어 설정에서 이미지 크기를 정의하고 the_post_thumbnail() 등으로 적절한 크기의 이미지를 불러온다.
  • 데이터베이스 쿼리 최소화: The Loop 등에서 불필요하게 많은 데이터베이스 쿼리를 실행하지 않도록 주의한다. 워드프레스 함수들은 대부분 최적화되어 있지만, 직접 WP_Query 등을 사용할 때는 성능을 고려해야 한다.

4. README.md

만든 테마를 다른 사람과 공유하거나 워드프레스 테마 디렉토리에 제출하려면, 테마에 대한 기본적인 정보와 사용법을 명확하게 제공해야 한다.

  • screenshot.png: 테마 폴더의 루트에 위치해야 하며, 워드프레스 관리자 화면의 ‘외모 > 테마’ 목록에서 테마의 모습을 보여주는 미리보기 이미지이다.
    권장 크기는 880×660 픽셀이다.
  • README.txt 또는 README.md: 테마에 대한 상세 정보를 담는 파일이다.
    테마의 이름, 설명, 버전, 제작자, 라이선스 정보, 최소 워드프레스 버전 요구 사항, 설치 방법, 주요 기능 설명, 사용자 정의 방법, 버그 신고 및 지원 방법 등 사용자가 테마를 이해하고 사용하는 데 필요한 모든 정보를 포함한다.

이 파일들은 테마의 전문성을 더해주고 사용자가 테마를 원활하게 사용할 수 있도록 돕는 중요한 부분이다.


이번 4편까지 다룬 내용들은 워드프레스 테마 개발의 기초부터 시작하여 기본적인 기능 구현 및 완성도를 높이는 필수적인 개념들이다.

사실 천천히 읽어보면 워드프레스 내에서만 적용되는 개념들이 아니라 개발 전반적으로 적용되는 개념도 포함되어 있다.

이후 학습을 통해 도전해 볼 만한 주제들은 다음과 같다.

  • Post Formats: 글의 형식(예: 스탠다드, 갤러리, 비디오, 인용구)에 따라 다른 스타일이나 레이아웃을 적용하는 방법.
  • Custom Post Types & Taxonomies: 글(Post)이나 페이지(Page) 외에 ‘상품’, ‘포트폴리오’, ‘영화’ 등 사용자 정의 콘텐츠 유형을 만들고, 이를 분류하기 위한 사용자 정의 카테고리/태그(Taxonomy)를 만드는 방법, 그리고 이를 테마에 표시하는 방법.
  • Editor Styles: 워드프레스 글/페이지 편집 화면에서 보여지는 스타일을 테마의 스타일과 유사하게 만들어, 사용자가 실제 웹사이트에서 어떻게 보일지 더 정확하게 예측할 수 있도록 하는 기능.
  • Block Editor (Gutenberg) 통합: 워드프레스 5.0부터 도입된 블록 에디터에 테마의 스타일을 적용하고, 테마에서 사용자 정의 블록 스타일이나 블록 패턴 등을 지원하는 방법. 더 나아가서는 FSE(Full Site Editing) 기능을 지원하는 블록 테마 개발.
  • AJAX 활용: 페이지 전체를 새로고침하지 않고 일부 콘텐츠만 동적으로 불러오거나 업데이트하는 방법 (예: ‘더보기’ 버튼 클릭 시 다음 글 목록 로드).
  • REST API 활용: 워드프레스 데이터를 외부 애플리케이션이나 JavaScript 프레임워크와 연동하는 방법.
  • 성능 최적화 심화: 캐싱, 이미지 지연 로딩(Lazy Loading), CSS/JS 압축 및 병합 등 전문적인 성능 최적화 기법 적용.

이 주제들은 테마 개발의 수준을 한 단계 더 높이고 특정 요구사항을 충족시키는 데 필요하다.

워드프레스 개발자 핸드북(developer.wordpress.org)은 정리가 매우 잘 되어 있는 가이드북이다. 필요하다면 정독하고, 그냥 훑어봐도 도움이 된다.


중요한 것은 직접 코드를 작성하고 테스트하며 오류를 수정하는 경험이다. 기존의 무료 테마 코드를 참고하고 분석하는 것도 매우 빠르고 훌륭한 학습 방법이다.

이제 각자의 테마를 만들어 보도록 하자.