WordPress.org

Codex

Page Templates

Pages are one of WordPress's built-in Post Types. You'll probably want most of your website Pages to look about the same. Sometimes, though, you may need a specific Page, or a group of Pages, to display or behave differently. This is easily accomplished with Page Templates.

Contents

Selecting a Page Template

Screenshot of Page Attributes module with Template select options pulled down

Your Theme files should include a default page template (named: page.php). Your Theme may also have one or more custom page templates, for instance, to display content in wider columns. Or you may have created a custom template of your own.

Edit Page Screen: You can assign a custom template for any individual Page by using the Template dropdown in the Edit Page screen (part of the Page Attributes module):

  1. Select a Template from the list (e.g., My Custom Page).
  2. Click the Update button (or Save Draft if not yet published).

All Pages Screen: The Quick-Edit and Bulk Edit options on the All Pages screen also have Template dropdowns.

Template List Will Show Only If:

  • There is at least one custom page template file in your active Theme's folder. If you change your Theme, the page templates in your previously activated Theme will not display.
  • You are viewing a screen for editing a Page: page templates are not a default option for posts or custom post types.

Creating a Page Template

WordPress offers several ways to display Pages. All involve editing or adding files in your active Theme's folder. If your active theme is not one that you have designed yourself, use a child theme to make the changes. Otherwise the changes will be overwritten when the theme is updated to a new version.

Conditional Tags

Edit your default template: You can often make smaller Page-specific changes with Conditional Tags in your Theme's page.php file. For instance, this code loads one header file (header-home.php) for your front page, another for your About page (header-about.php), and the default header.php for all other Pages:

if ( is_front_page() ) {
    get_header( 'home' );
} elseif ( is_page( 'About' ) ) {
    get_header( 'about' );
} else {
    get_header();
}

Specialized Page Template

Create a template for one Page: For more extensive changes, intended for just one specific Page, you can create a specialized template file, named with that Page's slug or ID:

  1. page-{slug}.php
  2. page-{ID}.php

For example: Your About page has a slug of 'about' and an ID of 6. If your active Theme's folder has a file named page-about.php or page-6.php, then WordPress will automatically find and use that file to render the About page.

To be used, specialized page templates must be in your active Theme's folder:

/wp-content/themes/my-theme/

A specialized page template file can not be in a sub-folder, nor, if using a Child Theme, in its Parent Theme's folder.

Custom Page Template

Create a template that can be used by any Page: A Custom Page Template can be used by multiple Pages (see Selecting a Page Template above). To create a custom page template make a new file starting with a Template Name inside a PHP comment. Here's the syntax:

<?php
/*
Template Name: My Custom Page
*/

Once you upload the file to your Theme's folder, the template name, "My Custom Page", will list in the Edit Page screen's Template dropdown. (The select list has a maximum width of 250px, so longer names may be cut off.)

A quick, safe method for making a new Page template is to use with a copy of your page.php: This way you start off with the HTML structure of your other pages, then you can edit as needed.

A custom page template file can be in a sub-folder, or, if using a Child Theme, in its Parent Theme's folder.

Filenames

Name your template file so you can easily identify its Template Name, e.g., filename my-custom-page.php for template name "My Custom Page". Some coders group their templates with a filename prefix, such as page_my-custom-page.php (Don't use page- prefix as WordPress will interpret the file as a specialized page template.)

For information on Theme file-naming conventions and filenames you cannot use, see reserved Theme filenames.

File Folders

To be used, a custom page template file must be stored (see FTP) in your active Theme's folder, or it Parent Theme's folder, or a sub-folder within either (since: 3.4.0). WordPress finds custom page templates in all these location:

/wp-content/themes/my-theme/
/wp-content/themes/my-theme/my-templates
/wp-content/themes/my-child-theme
/wp-content/themes/my-child-theme/my-templates
/wp-content/themes/my-parent-theme
/wp-content/themes/my-parent-theme/my-templates

For a file to be recognized as a custom page template, it must start with the string "Template Name:" in a comment. After that you can to add other information, like:

<?php
/*
 * Template Name: My Custom Page
 * Description: A Page Template with a darker design.
 */

// Code to display Page goes here...

The Template Tags article describes the many built-in WordPress Template functions you can use for page display.

What Page Gets What Template?

Template Terminology

The term "template" has several related uses in WordPress:

  • Template Hierarchy is the logic WordPress uses to decide which Theme template file(s) to use, depending on the request, e.g., the URL of a user-clicked link.

Template Hierarchy

Detail of WordPress Template Hierarchy flow chart, showing only Page Templates When a user requests a specific Page, the core WordPress code has logic that decides which Theme template to use for rendering that Page. The above image, a detail of the Template Hierarchy, diagrams that logic:

  1. Custom Template — If the Page has a custom Template assigned, WordPress looks for that file and, if found, uses it.
  2. page-{slug}.php Else WordPress looks for and, if found, uses a specialized template named with the Page's slug.
  3. page-{id}.php Else WordPress looks for and, if found, uses a specialized template named with the Page's ID.
  4. page.php Else WordPress looks for and, if found, uses the Theme's default page template.
  5. index.php Else WordPress uses a the Theme's index file.

(Note: There is also a WordPress-defined template named paged.php. It is not used for the Page post-type but rather for displaying multiple pages of Archives.)

Examples

The following are instructional examples of custom Page Template files. Note: Your WordPress Theme's template file structure and HTML structure may be different.

Archives with Content

This example of a Page Template display the Page's content at the top, then a list of archive (by month), then the site categories below that.

Save this to arc-cont.php:

<?php
/*
Template Name: Archives with Content
*/

get_header(); ?>
<div id="content" class="widecolumn">
    <?php if (have_posts()) : while (have_posts()) : the_post();?>
    <div class="post">
        <h2 id="post-<?php the_ID(); ?>"><?php the_title();?></h2>
        <div class="entrytext">
            <?php the_content('<p class="serif">Read the rest of this page »</p>'); ?>
        </div>
    </div>
    <?php endwhile; endif; ?>
<?php edit_post_link('Edit this entry.', '<p>', '</p>'); ?>
</div>
<div id="main">
    <?php get_search_form(); ?>
    <h2>Archives by Month:</h2>
    <ul>
        <?php wp_get_archives('type=monthly'); ?>
    </ul>   
    <h2>Archives by Subject:</h2>
    <ul>
        <?php wp_list_categories(); ?>
    </ul>
</div>
<?php get_footer(); ?>

A Page of Posts

The following custom page template file displays the content of the Page, followed by the posts from two specific categories (specified by their category slugs). It is designed to work within a child Theme of the Twenty Thirteen theme. If you are using a different theme, you need to replicate the HTML structure of your own theme within this template.

Save this to pageofposts.php and then assign the Page of Posts Template to your new Page:

<?php
/*
Template Name: Page Of Posts
*/

/* This example is for a child theme of Twenty Thirteen: 
*  You'll need to adapt it the HTML structure of your own theme.
*/

get_header(); ?>

	<div id="primary" class="content-area">
		<div id="content" class="site-content" role="main">
        <?php 
        /* The loop: the_post retrieves the content
         * of the new Page you created to list the posts,
         * e.g., an intro describing the posts shown listed on this Page..
         */
        if ( have_posts() ) :
            while ( have_posts() ) : the_post();

              // Display content of page
              get_template_part( 'content', get_post_format() ); 
              wp_reset_postdata();
  
            endwhile;
        endif;

        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

        $args = array(
            // Change these category SLUGS to suit your use.
            'category_name' => 'music, videos', 
            'paged' => $paged
        );

        $list_of_posts = new WP_Query( $args );
        ?>
        <?php if ( $list_of_posts->have_posts() ) : ?>
			<?php /* The loop */ ?>
			<?php while ( $list_of_posts->have_posts() ) : $list_of_posts->the_post(); ?>
				<?php // Display content of posts ?>
				<?php get_template_part( 'content', get_post_format() ); ?>
			<?php endwhile; ?>

			<?php twentythirteen_paging_nav(); ?>

		<?php else : ?>
			<?php get_template_part( 'content', 'none' ); ?>
		<?php endif; ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_footer(); ?>

Example Using Custom Fields

This Page Template example displays posts from a specific category depending on a Custom Field assigned to a Page. The value of the Custom Field "category" is retrieved and used as the category to retrieve the posts in that category. If the category of posts you want to display is called "Events" then assign the Custom Field "category" with a value of "Events" to the Page. Note that this will adhere to pagination rules meaning that four (4) posts will display per page with links to older/newer posts provided.

Save this to pageofposts.php and then assign the Page of Posts Template when creating the action Page:

<?php
/*
Template Name: Page Of Posts with Custom Fields
*/

get_header(); ?>
<div id="content" class="narrowcolumn">
<?php
if ( is_page() ) {
    $category = get_post_meta( $posts[0]->ID, 'category', true );
    $cat = get_cat_ID( $category );
}
if ( $cat ) :
    $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    $post_per_page = 4; // -1 shows all posts
    $do_not_show_stickies = 1; // 0 to show stickies
    $args=array (
      'category__in' => array( $cat ),
      'orderby' => 'date',
      'order' => 'DESC',
      'paged' => $paged,
      'posts_per_page' => $post_per_page,
      'ignore_sticky_posts' => $do_not_show_stickies
    );
    $temp = $wp_query; // assign original query to temp variable for later use  
    global $wp_query;
    $wp_query = null;
    $wp_query = new WP_Query( $args ); 
    if ( $wp_query->have_posts() ) : 
        while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
        <div <?php post_class() ?> id="post-<?php the_ID(); ?>">
            <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
            <small><?php the_time( 'F jS, Y' ) ?> <!-- by <?php the_author() ?> --></small>
            <div class="entry">
            <?php the_content( 'Read the rest of this entry »' ); ?>
            </div>
            <p class="postmetadata"><?php the_tags( 'Tags: ', ', ', '<br />' ); ?> Posted in <?php the_category( ', ' ) ?> | <?php edit_post_link( 'Edit', '', ' | ' ); ?> <?php comments_popup_link( 'No Comments »', '1 Comment »', '% Comments »' ); ?></p>
        </div>
        <?php endwhile; ?>
    <div class="navigation">
        <div class="alignleft"><?php next_posts_link( '« Older Entries' ) ?></div>
        <div class="alignright"><?php previous_posts_link( 'Newer Entries »' ) ?></div>
    </div>
 	<?php endif; // if ( $wp_query->have_posts() ) ?>
	<?php $wp_query = $temp; //reset back to original query ?>

<?php else : ?>
    <h2 class="center">Not Found</h2>
    <p class="center">Sorry, but you are looking for something that isn't here.</p>
    <?php get_search_form(); ?>    
<?php endif; // if ( $cat ) ?>

</div><!-- #content -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Example Using Custom Post Types

Custom Post Types allow WordPress sites to display many different types of content. This example displaying the posts on a Page belonging to a custom post type. In this case, the custom post type is book. The custom Page Template below can work in any Theme or as a Child Theme template file.

<?php
/**
 * Template Name: Page of Books
 *
 * Print posts of a Custom Post Type.
 */

get_header(); ?>
    <div id="container">
        <div id="content">
        <?php 
        $type = 'book';
        $args = array (
         'post_type' => $type,
         'post_status' => 'publish',
         'paged' => $paged,
         'posts_per_page' => 2,
         'ignore_sticky_posts'=> 1
        );
        $temp = $wp_query; // assign ordinal query to temp variable for later use  
        $wp_query = null;
        $wp_query = new WP_Query($args); 
        if ( $wp_query->have_posts() ) :
            while ( $wp_query->have_posts() ) : $wp_query->the_post();
                echo '<h2>'; 
                the_title();
                echo '</h2>'; 
                echo '<div class="entry-content">';
                the_content();
                echo '</div>';
            endwhile;
        else :
            echo '<h2>Not Found</h2>';
            get_search_form();
        endif;
        $wp_query = $temp;
        ?>
        </div><!-- #content -->
    </div><!-- #container -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Identifying a Page Template

If your template uses the body_class function, WordPress will print classes in the <body> tag for the post type (class name: page), the Page's ID (page-id-{ID}), and the page template used. For the default page.php the class name is page-template-default, e.g.:

<body class="page page-id-6 page-template-default">

Note: a specialized template (page-{slug}.php or page-{ID}.php) also gets the page-template-default class -- not its own body class.

When using a custom page template, the class page-template will print, along with a class naming the specific template, e.g.:

<body class="page page-id-6 page-template page-template-my-custom-page-php">

Page Template Functions

These built-in WordPress functions and methods can help you work with page templates:

The filename of a Page's assigned custom template is stored as the value of a Custom Field named '_wp_page_template' (in the wp_postmeta database table). (Custom fields starting with an underscore do not display in the Edit screen's Custom Fields module.)