Dissection of a WordPress theme: Part 4

Finishing the theme

Our theme is almost complete. All important elements are finished, leaving us with a few areas to tidy. If we look in the theme directory we will notice files that have not yet been touched:

  • 404.php
  • archive.php
  • comments-popup.php
  • search.php

404.php

This file lets you create a custom 404 error page that is displayed by WordPress and so retains the same layout and style. For this to work you need to redirect 404 errors to WordPress. How this is achieved varies, depending on your hosting company and web server.

For Apache-based websites where no administrative feature is provided, this involves adding the following to your .htaccess file:

ErrorDocument 404 /index.php?error=404

The URL should be changed to include the path of your WordPress installation. Now all errors will be directed to WordPress, which delegates the work to the 404.php file in our theme.

<?php get_header(); ?>

  <div id="content" class="narrowcolumn">
    <h2 class="center">Error 404 - Not Found</h2>
  </div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Although this is acceptable, it could be a lot better:

<?php get_header(); ?>
<div id="wrapper">

  <div id="content" class="narrowcolumn">

    <div class="post">
      <h2>Error 404 - Not Found</h2>

      <img style="float: left; width: 128px" src="<?php bloginfo('template_url') ?>/images/error.png"/>
      <p>You have tried to access something that doesn't exist.  It may have been moved or you may have been directed here in error.</p>

      <p>You can search the website here, or return to the front page and try again.</p>
      <p><?php include ('searchform.php') ?></p><br/>
      <div style="clear: left"></div>

      <p>Alternatively you might find what you need in this list of recent posts:</p>
      <p><?php wp_get_archives('type=postbypost&limit=10') ?></p>
    </div>
  </div>

<?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

Now the error page looks like:

404 page

A more helpful user experience!

archive.php

When you select a link from the ‘Archives’ section of the sidebar, WordPress delegates the work to the archive.php file. We need to update this to include our wrapper element otherwise the layout will not be consistent.

<?php get_header(); ?>

<div id="wrapper">
  <div id="content" class="narrowcolumn">
    <?php if (have_posts()) : ?>

    <?php $post = $posts[0]; // Hack. Set $post so that the_date() works. ?>

    <?php /* If this is a category archive */ if (is_category()) { ?>       
    <h2 class="pagetitle">Archive for the '<?php echo single_cat_title(); ?>' Category</h2>
   
    <?php /* If this is a daily archive */ } elseif (is_day()) { ?>
    <h2 class="pagetitle">Archive for <?php the_time('F jS, Y'); ?></h2>
  
    <?php /* If this is a monthly archive */ } elseif (is_month()) { ?>
    <h2 class="pagetitle">Archive for <?php the_time('F, Y'); ?></h2>

    <?php /* If this is a yearly archive */ } elseif (is_year()) { ?>
    <h2 class="pagetitle">Archive for <?php the_time('Y'); ?></h2>
  
    <?php /* If this is a search */ } elseif (is_search()) { ?>
    <h2 class="pagetitle">Search Results</h2>
   
    <?php /* If this is an author archive */ } elseif (is_author()) { ?>
    <h2 class="pagetitle">Author Archive</h2>

    <?php /* If this is a paged archive */ } elseif (isset($_GET['paged']) && !empty($_GET['paged'])) { ?>
    <h2 class="pagetitle">Blog Archives</h2>

    <?php } ?>

    <div class="navigation">
      <div class="alignleft"><?php posts_nav_link('','','&laquo; Previous Entries') ?></div>
      <div class="alignright"><?php posts_nav_link('','Next Entries &raquo;','') ?></div>
    </div>

    <?php while (have_posts()) : the_post(); ?>
    <div class="post">
       <h3 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h3>

       <small><?php the_time('l, F jS, Y') ?></small>
       
       <div class="entry">
          <?php the_excerpt() ?>
       </div>

       <p class="postmetadata">Posted in <?php the_category(', ') ?> <strong>|</strong> <?php edit_post_link('Edit','','<strong>|</strong>'); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
       
       <!-- <?php trackback_rdf(); ?> -->
    </div>
 
    <?php endwhile; ?>

    <div class="navigation">
      <div class="alignleft"><?php posts_nav_link('','','&laquo; Previous Entries') ?></div>
      <div class="alignright"><?php posts_nav_link('','Next Entries &raquo;','') ?></div>
    </div>
 
  <?php else : ?>

    <h2 class="center">Not Found</h2>
    <?php include (TEMPLATEPATH . '/searchform.php'); ?>

  <?php endif; ?>
  </div>

	<?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

This is similar to previous files, and makes use of The Loop and the template functions in ways that have already been discussed. The only additional change required is to add a style for ‘pagetitle’:

.pagetitle {
  color: #bd492a;
} 

comments-popup.php

This has been briefly touched on before, and is used to display comments in a popup window. By default this is disabled in index.php.

search.php

WordPress displays the results of a search using the search.php file. Again we need to add a wrapper element to this.

<?php get_header(); ?>

<div id="wrapper">
  <div id="content" class="narrowcolumn">

  <?php if (have_posts()) : ?>
    <h2 class="pagetitle">Search Results</h2>
  
    <div class="navigation">
      <div class="alignleft"><?php posts_nav_link('','','&laquo; Previous Entries') ?></div>
      <div class="alignright"><?php posts_nav_link('','Next Entries &raquo;','') ?></div>
    </div>

    <?php while (have_posts()) : the_post(); ?>
      <div class="post">
        <h3 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h3>
        <small><?php the_time('l, F jS, Y') ?></small>
       
        <div class="entry">
          <?php the_excerpt() ?>
        </div>
   
        <p class="postmetadata">Posted in <?php the_category(', ') ?> <strong>|</strong> <?php edit_post_link('Edit','','<strong>|</strong>'); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
      
        <!-- <?php trackback_rdf(); ?> -->
      </div>
 
    <?php endwhile; ?>

    <div class="navigation">
      <div class="alignleft"><?php posts_nav_link('','','&laquo; Previous Entries') ?></div>
      <div class="alignright"><?php posts_nav_link('','Next Entries &raquo;','') ?></div>
    </div>
 
  <?php else : ?>
    <h2 class="center">Not Found</h2>
    <?php include (TEMPLATEPATH . '/searchform.php'); ?>
  <?php endif; ?>
  </div>

	<?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

The code is almost identical to previous sections, and uses The Loop in a standard manner.

105 thoughts on “Dissection of a WordPress theme: Part 4”

  1. Superb, Stunning and Diligent… I was just looking how to design a WordPress theme from my HTML template and this is one tutorial which was just perfect. Thanks for all the painstaking documentation. God Bless!

  2. Thank YOU!

    I thought I knew CSS but one look at the Kubrick style.css made wonder whether I really knew it. Anyway, that look was enough to put aside the theme redesign project I had in mind, particularly when I found that whatever changes I make to the stylesheet, the header had the same blue background. It was only when I went through your tutorial that I really was able to identify the problem and go to the Admin panel of wordpress.

    Your tutorial provided many more such insights into small details with big impact.

    Above all, it provided the confidence to start on the theme redesign project.

    Once again, Thank YOU!

Leave a Reply

Your email address will not be published. Required fields are marked *