WordPress Theme Index Template

Index.php is the most crucial WordPress Theme Template. Not only because WordPress needs to use it if you’re missing any of it’s brother and sister templates (like, category.php or tag.php) but because the work we do here, getting this template right, will help us breeze through the rest of our templates (with the exception of the dreaded comments template; that’s just plain difficult no matter how you look at it).

The Loop

Even though it’s stuck right in the middle of your template, in a metaphorical sense index.php begins and ends with The Loop. Without it you don’t have anything. Here’s what it looks like.

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

Simple really. And not even deceptively simple. While you’ve got posts in your database your theme will loop through them and for each one, do something. Getting the “do something” just right is the tricky part. But even that can be simple.

Try out this loop to get started and we’ll work on building it up. Put the following code inside your #content div in index.php.

<?php while ( have_posts() ) : the_post() ?>
<?php the_content(); ?>
<?php endwhile; ?> 

What do you get if you do that? All the post content in a big smushed up pile. But it could be different.

<ul>
<?php while ( have_posts() ) : the_post() ?>
<li>
    <?php the_excerpt(); ?>
</li>
<?php endwhile; ?>        
</ul>

Do you see what we just did there? Now you’ve got an unordered list of post excerpts. (Plus, now you can see what the_content() and the_excerpt() do)

Basically, you make a loop (starts with while ends with endwhile) and put some stuff in it—stuff being WordPress Template Tags that pull information out of the posts we’re looping though, just like bloginfo() pulled information out of our WordPress settings in the last lesson.

Alright, let’s make a really awesome loop. Let’s start with our basic, smushed up one. But we’ll make sure it’s ready for the More Tag and the Next Page Tag. We’ll also put it in it’s own div and let machines know it’s the content of a blog post with the microformat class “entry-content”.

  <div class="entry-content">   
<?php the_content( __( 'Continue reading <span>&raquo;</span>', 'your-theme' )  ); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>
                    </div><!-- .entry-content -->
 

How about the post title? That’s pretty simple too. We’ll use the Template Tag the_title() to get the title of the post and wrap it in an a tag that links to the_permalink() (that’s the permanent link to any particular post). We’ll also add in a title attribute and another microformat (bookmark) that tells machines (like Google) that this is the permalink to a blog post. Try putting the following just above the .entry-content div.

<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>

Now for all the extra bits that attend to any blog post: who wrote it, the time it was published, categories, tags, comments links. I like to break all this up into two sections: the meta stuff (author and entry date) which I put before the post content, and the utility stuff (categories, tags and comments link) that I put after the content. And both sections We’ll also put the post in it’s own containing div with the title.

Let’s take a look at the whole loop together. I’ve inserted some PHP comments in here to help guide you along.

<?php /* The Loop — with comments! */ ?>          
<?php while ( have_posts() ) : the_post() ?>

<?php /* Create a div with a unique ID thanks to the_ID() and semantic classes with post_class() */ ?>        
                <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>             
<?php /* an h2 title */ ?>                            
                    <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
                     
<?php /* Microformatted, translatable post meta */ ?>                                     
                    <div class="entry-meta">
                        <span class="meta-prep meta-prep-author"><?php _e('By ', 'your-theme'); ?></span>
                        <span class="author vcard"><a class="url fn n" href="<?php echo get_author_link( false, $authordata->ID, $authordata->user_nicename ); ?>" title="<?php printf( __( 'View all posts by %s', 'your-theme' ), $authordata->display_name ); ?>"><?php the_author(); ?></a></span>
                        <span class="meta-sep"> | </span>
                        <span class="meta-prep meta-prep-entry-date"><?php _e('Published ', 'your-theme'); ?></span>
                        <span class="entry-date"><abbr class="published" title="<?php the_time('Y-m-d\TH:i:sO') ?>"><?php the_time( get_option( 'date_format' ) ); ?></abbr></span>
                        <?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t" ) ?>
                    </div><!-- .entry-meta -->

<?php /* The entry content */ ?>                  
                    <div class="entry-content">   
<?php the_content( __( 'Continue reading <span>&raquo;</span>', 'your-theme' )  ); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>
                    </div><!-- .entry-content -->

<?php /* Microformatted category and tag links along with a comments link */ ?>                   
                    <div class="entry-utility">
                        <span class="cat-links"><span class="entry-utility-prep entry-utility-prep-cat-links"><?php _e( 'Posted in ', 'your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span>
                        <span class="meta-sep"> | </span>
                        <?php the_tags( '<span><span>' . __('Tagged ', 'your-theme' ) . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?>
                        <span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'your-theme' ), __( '1 Comment', 'your-theme' ), __( '% Comments', 'your-theme' ) ) ?></span>
                        <?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t\n" ) ?>
                    </div><!-- #entry-utility -->   
                </div><!-- #post-<?php the_ID(); ?> -->

<?php /* Close up the post div and then end the loop with endwhile */ ?>      
     
<?php endwhile; ?>      

Navigation

Now we need a way to navigate back through our posts. We’ll do this with 2 WordPress Template Tags: next_posts_link() and previous_posts_link(). These 2 functions … they don’t do what you think they do. I think the WordPress codex says it best.

next posts link
This creates a link to the previous posts. Yes, it says “next posts,” but it’s named that just to confuse you.
previous posts link
This creates a link to the next posts. Yes, it says “previous posts,” but it’s named that just to confuse you.

Just like everything in index.php, post navigation needs to be given some careful thought when we’re building it for the first time because we’re going to wind up using it on almost every page in our blog.

I like to have post navigation above and below the content. Depending on how you use this code in any particular situation, you may not use it though. No matter, we can always hide it like so.

.single #nav-above {
    display:none;
}

That CSS will hide post navigation above the content on single posts.

We’ll also want to hide any navigation code IF there’s nothing to navigate too. That is, if, say, on a search, there are no older pages of posts, we don’t want to output any navigation code at all to the browser. We’ll do that by wrapping our code in the following statement:

<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
<?php } ?>

What we’re doing is checking to see what the maximum number of pages is in any loop we’re going to be looking at and if the number of pages is greater than 1, we’ll output our navigation.

Alright, here’s the code we’ll need for your navigation, top and bottom, just before, and just after the loop.

<?php /* Top post navigation */ ?>
<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
                <div id="nav-above" class="navigation">
                    <div class="nav-previous"><?php next_posts_link(__( '<span>&laquo;</span> Older posts', 'your-theme' )) ?></div>
                    <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
                </div><!-- #nav-above -->
<?php } ?>            

<?php /* Bottom post navigation */ ?>
<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
                <div id="nav-below" class="navigation">
                    <div class="nav-previous"><?php next_posts_link(__( '<span>&laquo;</span> Older posts', 'your-theme' )) ?></div>
                    <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
                </div><!-- #nav-below -->
<?php } ?>      

One last thing and we’re done index.php. You’ll be itching to see what we can do with it, but for now we’re just going to put in the function call just before get_footer().

<?php get_sidebar(); ?>
  1. WordPress Theme Tutorial Introduction
  2. Theme Development Tools
  3. Creating a Theme HTML Structure
  4. Template and Directory Structure
  5. The Header Template
  6. The Index Template
  7. The Single Post, Post Attachment, & 404 Templates
  8. The Comments Template
  9. The Search Template & The Page Template
  10. The Archive, Author, Category & Tags Template
  11. The Sidebar Template
  12. Reset-Rebuild Theme CSS & Define Your Layouts
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s