WordPressIf you take a look at the template hierarchy in WordPress, you will notice that you have the ability to create custom templates for different category pages by simply adding the category slug or id to the end of your filename. So category-articles.php will be called before category.php if you query the Articles category. But what if you wanted to have a custom template for every post in the Articles category so that it displayed differently from posts in other categories. By default that can’t be done unless you do a little hacking.

Here is an easy way to create custom templates for single posts in WordPress.

First, we need to figure out the category id of the posts we want to customize. Open up your wp-admin and go to the Categories page. Click on the category you want and then take a look in the address bar. You should see something like this:

catid

The 32 at the end is your category id.

Now open up your single.php file and let’s make a few changes. I will use the single.php file from the Default theme as an example.

<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/

get_header();
?>

<div id="content" role="main">

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

<div>
<div><?php previous_post_link('&laquo; %link') ?></div>
<div><?php next_post_link('%link &raquo;') ?></div>
</div>

<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>

<div>
<?php the_content('<p>Read the rest of this entry &raquo;</p>'); ?>

<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
<?php the_tags( '<p>Tags: ', ', ', '</p>'); ?>

<p>
<small>
This entry was posted
<?php /* This is commented, because it requires a little adjusting sometimes.
You'll need to download this plugin, and follow the instructions:
http://binarybonsai.com/wordpress/time-since/ */
/* $entry_datetime = abs(strtotime($post->post_date) - (60*120)); echo time_since($entry_datetime); echo ' ago'; */ ?>
on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>
and is filed under <?php the_category(', ') ?>.
You can follow any responses to this entry through the <?php post_comments_feed_link('RSS 2.0'); ?> feed.

<?php if ( comments_open() && pings_open() ) {
// Both Comments and Pings are open ?>
You can <a href="#respond">leave a response</a>, or <a href="<?php trackback_url(); ?>" rel="trackback">trackback</a> from your own site.

<?php } elseif ( !comments_open() && pings_open() ) {
// Only Pings are Open ?>
Responses are currently closed, but you can <a href="<?php trackback_url(); ?> " rel="trackback">trackback</a> from your own site.

<?php } elseif ( comments_open() && !pings_open() ) {
// Comments are open, Pings are not ?>
You can skip to the end and leave a response. Pinging is currently not allowed.

<?php } elseif ( !comments_open() && !pings_open() ) {
// Neither Comments, nor Pings are open ?>
Both comments and pings are currently closed.

<?php } edit_post_link('Edit this entry','','.'); ?>

</small>
</p>

</div>
</div>

<?php comments_template(); ?>

<?php endwhile; else: ?>

<p>Sorry, no posts matched your criteria.</p>

<?php endif; ?>

</div>

<?php get_footer(); ?>

To get this little hack to work all you need to do is add:

<?php
if(in_category(32)) {
// Custom Template for Single Posts in Category 32
include 'single-32.php';
} else {
?>

On line #1 and:


All the way at the bottom.

So now your single.php file should look like this:

<?php
if(in_category(32)) {
include 'single-32.php';
} else {
?>
<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/

get_header();
?>

<div id="content" role="main">

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

<div>
<div><?php previous_post_link('&laquo; %link') ?></div>
<div><?php next_post_link('%link &raquo;') ?></div>
</div>

<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>

<div>
<?php the_content('<p>Read the rest of this entry &raquo;</p>'); ?>

<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
<?php the_tags( '<p>Tags: ', ', ', '</p>'); ?>

<p>
<small>
This entry was posted
<?php /* This is commented, because it requires a little adjusting sometimes.
You'll need to download this plugin, and follow the instructions:
http://binarybonsai.com/wordpress/time-since/ */
/* $entry_datetime = abs(strtotime($post->post_date) - (60*120)); echo time_since($entry_datetime); echo ' ago'; */ ?>
on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>
and is filed under <?php the_category(', ') ?>.
You can follow any responses to this entry through the <?php post_comments_feed_link('RSS 2.0'); ?> feed.

<?php if ( comments_open() && pings_open() ) {
// Both Comments and Pings are open ?>
You can <a href="#respond">leave a response</a>, or <a href="<?php trackback_url(); ?>" rel="trackback">trackback</a> from your own site.

<?php } elseif ( !comments_open() && pings_open() ) {
// Only Pings are Open ?>
Responses are currently closed, but you can <a href="<?php trackback_url(); ?> " rel="trackback">trackback</a> from your own site.

<?php } elseif ( comments_open() && !pings_open() ) {
// Comments are open, Pings are not ?>
You can skip to the end and leave a response. Pinging is currently not allowed.

<?php } elseif ( !comments_open() && !pings_open() ) {
// Neither Comments, nor Pings are open ?>
Both comments and pings are currently closed.

<?php } edit_post_link('Edit this entry','','.'); ?>

</small>
</p>

</div>
</div>

<?php comments_template(); ?>

<?php endwhile; else: ?>

<p>Sorry, no posts matched your criteria.</p>

<?php endif; ?>

</div>

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

Now all you need to do is create a file called single-32.php and add it to your theme. Code that file however you want your single page posts in category 32 to appear and you are done.

You can also use this hack if you want to create a custom template for a specific post. Just replace in_category() with is_page().