Creating book template files

WordPress needs to know how to display your new post type. You have to create a template for a single book, and one for the listing of books. Perform the following steps to do this: 

  1. First, we'll make a book version of single.php. It must be named single-POST_TYPE_NAME.php, which in our case is single-book.php.
  1. Using page.php as our starting point (as it's already the closest to what we'd like our book page to look like), we're going to add the display of the custom field, book_author, and the featured image.
  2. So, let's start by taking our page.php file, making a copy of it, and renaming it single-book.php. Also, let's make a copy of content-page.php and call it content-book.php.
  3. Next, it's time to include all the elements. Here's what the two files look like. First, single-book.php looks like this:
<?php 
/** 
 * The template for displaying a single book. 
 * 
 * @package Daily Cooking Custom 
 */ 
?><?php get_header(); ?> 
 
<div id="primary" class="content-area"> 
  <main id="main" class="site-main" role="main"> 
    <?php while (have_posts()) : the_post(); ?> 

      <?php get_template_part('content', 'book'); ?> 

    <?php endwhile; // end of the loop. ?> 

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

<?php get_sidebar(); ?> 
<?php get_footer(); ?>

The only change that's been made to this file is the get_template_part() function call.

  1. Next, the content-book.php file looks like the following:
<?php 
/** 
 * The template used for displaying book content 
 * 
 * @package Daily Cooking Custom 
 */ 
?> 
 
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 
  <header class="entry-header"> 
    <?php the_title('<h1 class="entry-title">', '</h1>'); ?> 
  </header> 

  <div class="entry-content"> 
    <?php if(has_post_thumbnail()) : ?> 
      <div class="post-image alignleft">
      <?php echo get_the_post_thumbnail($post->ID, 'medium', 
      array('style' => 'border: 1px solid black;')); ?></div> 
    <?php endif; ?> 
    <?php the_content(); ?> 
  </div> 

  <footer class="entry-footer"> 
  </footer> 
</article><!-- #post-## -->
  1. Now, let's take our custom field, book_author, and display it right below the featured image. We can do this by adding one new line of code in between the featured image code and the main content code, as shown in the following code snippet:
<?php if(has_post_thumbnail()) : ?> 
  <div class="post-image alignleft">
  <?php echo get_the_post_thumbnail($post->ID, 'medium', 
  array('style' => 'border: 1px solid black;')); ?></div> 
<?php endif; ?> 
<?php echo '<p><em>by '.get_post_meta($post->ID, 'book_author', true).
'</em></p>'; ?> 
<?php the_content(); ?>
  1. At this point, when you visit a single book page, the author's name is displayed and the book cover shows up automatically, as shown in the following screenshot:

  1. Our next task is a page that will show a listing of the books, like what index.php does for the posts. By default, WordPress uses the archive.php file to show the listing of every new custom post type.

We can customize this by creating a new template file and calling it archive-book.php. To be more exact, every template file controlling the archive for any new custom post type has to be named archive-POST_TYPE.php. The easiest way to create such file is by making a copy of the standard archive.php file or the index.php file, and renaming it to archive-book.php. Then, we can take it from there and modify the file to fit our requirements. So, what I'm going to do here is use my index.php as the template and do some tuning up around it.

  1. Right now, my new archive-book.php file doesn't offer any custom way of displaying my books. What it looks like is shown in the following code:
<?php 
/** 
 * The listing of books. 
 * 
 * @package Daily Cooking Custom 
 */ 
?><?php get_header(); ?> 
 
  <div id="primary" class="content-area"> 
    <main id="main" class="site-main" role="main"> 

    <?php if (have_posts()) : ?> 

      <?php /* Start the Loop */ ?> 
      <?php while (have_posts()) : the_post(); ?> 
      <?php get_template_part('listing', 'book'); ?> 
      <?php endwhile; ?> 

      <?php daily_cooking_custom_paging_nav(); ?> 

    <?php else : ?> 

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

    <?php endif; ?> 

    </main><!-- #main --> 
  </div><!-- #primary --> 
 
<?php get_sidebar(); ?> 
<?php get_footer(); ?>
  1. As you can see, the actual display is done by the get_template_part('listing', 'book') function call. In order to make this line work, we have to create the listing file itself. The simplest way of doing this is by making a copy of content.php and modifying it slightly. First, rename it to listing-book.php.
  1. Right away, I'm going to erase the unnecessary sections and leave only those that can be used to make our book listing look great.
  2. Next, I will also include a thumbnail display. Quite frankly, I don't have to do this, but I believe that the book listing will look better with smaller thumbnails.
  3. Finally, I will also display the author of each book. The following code shows how the finished file will look:
<?php 
/** 
 * @package Daily Cooking Custom 
 */ 
?> 
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 
  <header class="entry-header"> 
    <?php the_title(sprintf('<h1 class="entry-title">"<a href="%s"  
    rel="bookmark">', esc_url(get_permalink())), '</a>"</h1>'); ?> 
  </header> 

  <div class="entry-content"> 
    <?php if(has_post_thumbnail()) : ?> 
      <div class="post-image alignleft"> 
        <?php echo '<a href="'.esc_url(get_permalink()).'" 
        >'.get_the_post_thumbnail($post->ID, 'thumbnail').'</a>'; ?> 
      </div> 
    <?php endif; ?> 

    <div class="entry clearfix"> 
      <p><em>by <?php echo get_post_meta($post->ID,
      'book_author', true); ?>
      </em></p> 
      <?php the_content(sprintf(__('Continue reading %s 
      <span class="meta-nav">&rarr;</span>', 'daily-cooking-custom'), 
      the_title('<span class="screen-reader-text">"', 
      '"</span>', false))); 
      ?> 
    </div> 
  </div> 

  <footer class="entry-footer"> 
  </footer> 
</article><!-- #post-## -->
  1. The following screenshot shows the final effect (I've added one more book just for demonstration purposes):