theme 만들기 from scratch (1) 글에선 최소 단위의 theme를 만들어보았다. 이번 포스팅에선 앞서 잠시 설명했던 Template 파일들을 활용해보도록 한다.
wordpress는 post나 page들의 글을 작성하면 별도의 file이 생성되는 게 아니라, DB에 내용을 저장하고 사용자가 해당 글을 요청하는 경우 template 파일에서 DB에 저장된 데이터를 읽어들여 서비스하는 구조를 가지고 있다. 따라서 개별 글이 아닌 Template 파일들이 실제 웹브라우저에 보여주는 방법을 정의하는 파일들이다.
WordPress의 Theme Handbook에선 Template 파일 활용, Hook 등 Function 활용, Option 등의 순으로 설명이 되어 있다. Hook을 활용하는 게 더 좋다는 글이 있더라도 어쨋건 Template 파일 활용이 가장 먼저 이해해야할 기초가 된다는 말이다.
Contents
1. 준비 작업
Template이 어찌 보이는 지 명확히 확인해보기 위해 몇 개 Post와 Page를 만들어보자. 각 Post와 Page에는 첨부 파일도 추가하고, Comment도 추가한다.
2. Post Templates

1) index.php
각각의 Post Type에 대한 specific한 Template File이 없는 경우 최종적으로 index.php 템플릿을 사용하여 화면을 출력한다.
많은 경우 index.php 파일을 사용하여 화면을 출력하기 보다, home.php나 single.php와 같은 좀 더 Specific한 Template들을 많이 사용하게 된다.
만약 index.php에서 모든 Post Type을 모두 처리하려고 한다면 Post Type을 확인하고, 각 Type에 따라 if, elseif 문을 지저분하게 사용해야 할 것이다.
index.php 파일을 다음과 같이 수정하고, 웹브라우저에서 다양한 경로(즉, post type들을 요청)로 index.php 템플릿에 접근해보자.
<table border="1"> <tr> <th>function</th> <th>value</th> </tr> <tr> <td>is_home()</td> <td><?php var_export(is_home());?></td> </tr> <tr> <td>is_page()</td> <td><?php var_export(is_page());?></td> </tr> <tr> <td>is_front_page()</td> <td><?php var_export(is_front_page());?></td> </tr> <tr> <td>is_search()</td> <td><?php var_export(is_search());?></td> </tr> <tr> <td>have_posts()</td> <td><?php var_export(have_posts());?></td> </tr> <tr> <td>get_option( 'show_on_front' )</td> <td><?php var_export(get_option( 'show_on_front' )); ?></td> </tr> <tr> <td>get_option( 'page_on_front' )</td> <td><?php var_export(get_option( 'page_on_front' )); ?></td> </tr> <tr> <td>get_option( 'page_for_posts' )</td> <td><?php var_export(get_option( 'page_for_posts' )); ?></td> </tr> </table>
결과는 다음과 같다.
URL | is_home | is_page | is_front_page | is_search | have_posts |
---|---|---|---|---|---|
/ (root) | true | false | true | false | true / false (존재여부따라) |
/post슬러그/ | false | false | false | false | true / false (존재여부따라) |
/page슬러그/ | false | true | false | false | true / false (존재여부따라) |
/category/카테고리슬러그/ | false | false | false | false | true / false (존재여부따라) |
/author/아이디/ | false | false | false | false | true / false (존재여부따라) |
** twenty twenty 테마등의 index.php를 살펴보면 위 함수들을 사용하여 post type별 처리를 하는 코드를 발견할 수 있다.
2) home.php
사이트 root url로 접근하면 home.php 템플릿에서 화면을 생성한다. 만약 home.php 템플릿이 없다면 역시 index.php 템플릿이 활용된다.
설정/읽기/홈페이지 표시 Option의 기본 값은 ‘최근 글’로 되어 있다. 이 경우 home.php 템플릿을 활용하지만 만약 위 Option을 ‘정적인 Page’로 선택하고, 홈페이지(Page 파일 선택) 또는 글 페이지(Post 리스트를 보여줄 blank Page 파일 선택)를 선택하는 경우 front-page.php 템플릿을 선택하도록 할 수 있다.

즉, 테마를 만들 때 home.php와 front-page.php를 다르게 구현하면, 사용자들의 옵션 선택에 따라 디테일하게 화면의 변화를 설계할 수 있다는 말이다.
3) single.php
테마를 만들 때 불필요하게 많은 템플릿을 사용하지 않아야 한다. 하지만 single.php는 대부분의 테마에서 활용되고 있다. twenty sixteen 테마의 single.php 파일을 살펴보자.
<?php /** * The template for displaying all single posts and attachments * * @package WordPress * @subpackage Twenty_Sixteen * @since Twenty Sixteen 1.0 */ get_header(); ?> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <?php // Start the loop. while ( have_posts() ) : the_post(); // Include the single post content template. get_template_part( 'template-parts/content', 'single' ); // If comments are open or we have at least one comment, load up the comment template. if ( comments_open() || get_comments_number() ) { comments_template(); } if ( is_singular( 'attachment' ) ) { // Parent post navigation. the_post_navigation( array( 'prev_text' => _x( '<span class="meta-nav">Published in</span><span class="post-title">%title</span>', 'Parent post link', 'twentysixteen' ), ) ); } elseif ( is_singular( 'post' ) ) { // Previous/next post navigation. the_post_navigation( array( 'next_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Next', 'twentysixteen' ) . '</span> ' . '<span class="screen-reader-text">' . __( 'Next post:', 'twentysixteen' ) . '</span> ' . '<span class="post-title">%title</span>', 'prev_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Previous', 'twentysixteen' ) . '</span> ' . '<span class="screen-reader-text">' . __( 'Previous post:', 'twentysixteen' ) . '</span> ' . '<span class="post-title">%title</span>', ) ); } // End of the loop. endwhile; ?> </main><!-- .site-main --> <?php get_sidebar( 'content-bottom' ); ?> </div><!-- .content-area --> <?php get_sidebar(); ?> <?php get_footer(); ?>
4) archive.php
<?php /** * The template for displaying archive pages * * Used to display archive-type pages if nothing more specific matches a query. * For example, puts together date-based pages if no date.php file exists. * * If you'd like to further customize these archive views, you may create a * new template file for each one. For example, tag.php (Tag archives), * category.php (Category archives), author.php (Author archives), etc. * * @link https://developer.wordpress.org/themes/basics/template-hierarchy/ * * @package WordPress * @subpackage Twenty_Sixteen * @since Twenty Sixteen 1.0 */ get_header(); ?> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <?php if ( have_posts() ) : ?> <header class="page-header"> <?php the_archive_title( '<h1 class="page-title">', '</h1>' ); the_archive_description( '<div class="taxonomy-description">', '</div>' ); ?> </header><!-- .page-header --> <?php // Start the Loop. while ( have_posts() ) : the_post(); /* * Include the Post-Format-specific template for the content. * If you want to override this in a child theme, then include a file * called content-___.php (where ___ is the Post Format name) and that will be used instead. */ get_template_part( 'template-parts/content', get_post_format() ); // End the loop. endwhile; // Previous/next page navigation. the_posts_pagination( array( 'prev_text' => __( 'Previous page', 'twentysixteen' ), 'next_text' => __( 'Next page', 'twentysixteen' ), 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>', ) ); // If no content, include the "No posts found" template. else : get_template_part( 'template-parts/content', 'none' ); endif; ?> </main><!-- .site-main --> </div><!-- .content-area --> <?php get_sidebar(); ?> <?php get_footer(); ?>
위 코드는 twenty sixteen 테마의 archive.php 파일이다. 만약 사용자에 대해 좀 더 다른 화면 구성이 필요할 수도 있다. 사용자명, gravatar나 기타 정보들을 이용하여 사용자 화면을 다르게 구성해야 하면 author.php 템플릿을 활용할 수도 있다.
5) search.php
대부분의 테마들은 search.php 템플릿을 사용하고 있다.
<?php /** * The template for displaying search results pages * * @package WordPress * @subpackage Twenty_Sixteen * @since Twenty Sixteen 1.0 */ get_header(); ?> <section id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <?php if ( have_posts() ) : ?> <header class="page-header"> <h1 class="page-title"> <?php /* translators: %s: The search query. */ printf( __( 'Search Results for: %s', 'twentysixteen' ), '<span>' . esc_html( get_search_query() ) . '</span>' ); ?> </h1> </header><!-- .page-header --> <?php // Start the loop. while ( have_posts() ) : the_post(); /** * Run the loop for the search to output the results. * If you want to overload this in a child theme then include a file * called content-search.php and that will be used instead. */ get_template_part( 'template-parts/content', 'search' ); // End the loop. endwhile; // Previous/next page navigation. the_posts_pagination( array( 'prev_text' => __( 'Previous page', 'twentysixteen' ), 'next_text' => __( 'Next page', 'twentysixteen' ), 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>', ) ); // If no content, include the "No posts found" template. else : get_template_part( 'template-parts/content', 'none' ); endif; ?> </main><!-- .site-main --> </section><!-- .content-area --> <?php get_sidebar(); ?> <?php get_footer(); ?>
위 템플릿은 while문 안에서 get_template_part 함수를 사용하여 template-parts/content-search.php 서브 템플릿을 불러와서 화면을 구성한다.
3. Page Templates
page 템플릿은 이름에서 알 수 있듯이 page 포스트 타입을 위한 템플릿이다. 여러 page 템플릿을 가지고 있는 경우 특정 page에만 적용할 수도, 특정 그룹의 page들에 적용할 수도 있다.

1) Page Template
page_*.php 템플릿을 만드는 가장 쉬운 방법은 page.php 파일을 복사하여 수정하여 사용하는 것이다. 정의된 Page 템플릿은 글을 작성할 때 해당 Template을 선택할 수 있다.

이 Page 템플릿을 작성할 땐 주석에 Template 이름을 넣어준다. 만약 page_full-width.php 템플릿을 사용한다고 가정하면, 주석은 다음과 같이 작성될 수 있다.
<?php /* Template Name: Full Width */ ?>
만약 사용자 선택이 아니라 특정한 Post Type에 대해 적용되는 Page Template을 만드는 경우 다음과 같이 Post Type을 지정하면 된다.
<?php /* Template Name: Full-width Template Post Type: post, page, event */ // Page code here...
2) page-{slug}.php, page-{ID}.php
특정한 slug나 id를 갖는 page에 적용된다.
4. Attachment Templates
첨부파일 등에 적용되는 Template이며, Mime-Type등에 따라 좀 더 specific한 템플릿을 가질 수도 있다.
5. Custom Post Type Templates
6. Partial and Miscellaneous Tmplates
Footnotes
- 홈페이지 표시 옵션에 대한 설명은 다음 문서를 참고한다. https://wordpress.org/support/article/creating-a-static-front-page/
One Response
정말 이해하기 쉽게 친절히 설명해 놓으셨네요. 잘 읽고가요~!!
참 !! 2번내용도 참으로 궁금합니다.!