Displaying single custom post type items using custom templates

Displaying single custom post type items using custom templates


Custom post types straddle the line between plugin development and theme development since displaying any information that is specific to these new elements requires the creation of custom template files in the theme directory.

While it is not possible to create a solution that will work for all themes, a good practice that can be followed by plugin developers is to display the new data using the default WordPress theme. This way, users configuring the plugin on their site can see what needs to be done and adapt the code to their own theme.

This recipe shows how to create a template file to display all elements that we stored in the Book Review created in the previous recipe.

Getting ready

You should have already followed the Adding to the custom post type editor recipe to have a starting point for this recipe. Alternatively, you can get the resulting code (ch4-book-reviews\ch4-book-reviews-v2.php) from the downloaded code bundle and rename the file to ch4-book-reviews.php.

How to do it...

  1. 1. Navigate to the ch4-book-reviews folder of the WordPress plugin directory of your development installation.

  2. 2. Open the ch4-book-reviews.php file in a code editor.

  3. 3. Add the following line of code after the existing functions and before the closing ?> PHP command at the end of the file to register a function to be called when the administration interface is visited:

    add_filter( 'template_include',
    'ch4_br_template_include', 1 );
    
  4. 4. Add the following code section to provide an implementation for the ch4_br_template_include function:

    function ch4_br_template_include( $template_path ) {
    if ( get_post_type() == 'book_reviews' ) {
    if ( is_single() ) {
    // checks if the file exists in the theme first,
    // otherwise serve the file from the plugin
    if ( $theme_file = locate_template( array ( 'single-book_reviews.php' ) ) ) {
    $template_path = $theme_file;
    } else {
    $template_path = plugin_dir_path( __FILE__ ) . '/single-book_reviews.php';
    }
    }
    }
    return $template_path;
    }
    
  5. 5. Save and close the plugin file.

  6. 6. Create a new code file called single-book_reviews.php and open it in a code editor.

  7. 7. Add the following code in the file to create a template to display Book Reviews, including their custom fields:

    <?php get_header(); ?>
    <div id="primary">
    <div id="content" role="main">
    <!-- Cycle through all posts -->
    <?php while ( have_posts() ) : the_post(); ?>
    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
    <!-- Display featured image in right-aligned floating div -->
    <div style="float: right; margin: 10px">
    <?php the_post_thumbnail( 'large' ); ?>
    </div>
    <!-- Display Title and Author Name -->
    <strong>Title: </strong><?php the_title(); ?><br />
    <strong>Author: </strong>
    <?php echo esc_html( get_post_meta( get_the_ID(), 'book_author', true ) ); ?>
    <br />
    <!-- Display yellow stars based on rating -->
    <strong>Rating: </strong>
    <?php
    $nb_stars = intval( get_post_meta( get_the_ID(), 'book_rating', true ) );
    for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
    if ( $star_counter <= $nb_stars ) {
    echo '<img src="' .
    plugins_url( 'ch4-book-reviews/star-icon.png' ) .
    '" />';
    } else {
    echo '<img src="' .
    plugins_url ( 'ch4-book-reviews/star-icon-grey.png' )
    . '" />';
    }
    }
    ?>
    </header>
    <!-- Display book review contents -->
    <div class="entry-content"><?php the_content(); ?></div>
    </article>
    <!-- Display comment form -->
    <?php comments_template( '', true ); ?>
    <?php endwhile; ?>
    </div>
    </div>
    <?php get_footer(); ?>
    
  8. 8. Save and close the template file.

  9. 9. Find and download a PNG format pixel star icon measuring 32 x 32 pixels from a site such as IconArchive (http://www.iconarchive.com) and save it as star-icon.png in the plugin directory.

  10. 10. Create a black-and-white version of the star icon using any graphic processing tool and save it as star-icon-grey.png.

  11. 11. Go to the Book Reviews management page and click on the View link under the existing entry created in the previous recipe to see the content rendered using the new template.

How it works...

When rendering any web page, the default WordPress functionality is to search the current theme directory for an applicable template suitable for the content at hand. In the case of a single custom post type item such as a Book Review, it first looks for a single item template named single-<post-type-name>.php, where the latter part is the actual post type name. If it does not find this file, it defaults to the general single item template. In the first recipe of this chapter, the template that was used to show the Book Review was the default single item template, simply named single.php. To add better support for our new post type, this recipe associates a function with the template_include filter hook to change that behavior. More specifically, we use the locate_template function to check if the user provided a template for the book_reviews post type in the theme directory. If no template was found, we change the template path to load a template that we provide as part of the plugin files. This gives users the flexibility to use our template, which is more specific than the generic single item template, or to provide their own.

The rest of the recipe creates a new default template for Book Reviews, following standard theme mechanics, starting with the display of the site header and followed with a PHP while loop that cycles through all posts to be displayed (a single one in the case of a specific Book Review). This is followed by a number of WordPress template functions, such as the_title() and the_content(), to display various elements of the current post item.

To round out the page layout, the template contains code that displays the featured image along with the book title, its author, and its rating before showing the main content of the review and a comment form.

Out of these elements, the author and rating use a new function that we have not encountered yet called get_post_meta. This function is used to retrieve data that was stored in the custom fields section of the post editor and has three parameters:

get_post_meta( $post_id, $field_name, $single );

The first parameter is the post ID, which can easily be retrieved using the get_the_ID() template function. This ID is used to identify the post to which the custom information is associated. The second argument is the custom field name, which should match the name specified when it is created in the post editor. The third and final argument indicates if the return value should be a single value or an array of values. If set to false, it will produce an array containing a single element even if the custom field only contains a single value. In most cases, it should be set to true to receive a single value that can be accessed directly.

See also

  • Creating a custom post type recipe