The WordPress ‘Default’ Theme Demystified – Part One

MD 012006  /  7 comments

It seems that more designers and developers are using WordPress as a full-powered Content Management System rather than just stand-alone blogging software. The secret to WordPress’ success lies in its solid architecture and robust set of customizable tags. WordPress is at the center of this site and everything revolves around the ability to update and make changes easily. Although there are a lot of ’static’ areas to my current layout, I am working on a new version that fully incorporates the WordPress ‘Loop’ and will offer even more flexibility for future growth. I want to share some of the ways I have learned to use WordPress on this site and others in the hopes of shedding some light on its potential. I plan on writing up several tutorials over the next few weeks that will help demystify what happens behind the scenes of WordPress. I hope to release one tutorial covering a different set of topics once every week, so if you like this, please come back for more.

Before I start, I need to give credit where credit is due. A lot of what I know now is directly attributed to the WordPress Codex and Support Forums. These two resources are a seemingly endless wealth of knowledge and without them I’d still be completely in the dark. If you want to learn WordPress, and I mean really get into the software, then you must become familiar with the Codex and get involved in the Forums. Many people have spent a lot of time working on the exact same problems you’re having right now. Trust me, the answer is out there. Also this write up assumes a basic understanding of XHTML and PHP, but if you are new to either or both, you should be able to follow along without too much problem.

For my first tutorial, I will dive into the Default Template 1.5 that comes boxed with every new WordPress installation. More specifically, I will pick apart index.php and try to break it into manageable chunks that will be easy to understand. I think this is relevant because as a rule of thumb, I usually start all of my projects by making adjustments and building off of the WordPress Default 1.5 template. It’s well written, structurally sound and relatively easy to understand. Not to mention it’s easy to customize once you get the hang of it. So if you’re ready, lets go ahead and get started.

And it goes a little something like this

What better place to start than from the top? Whether working locally on your own machine or server-side with an existing live site, the file that calls WordPress into action is index.php.

At the top of index .php, you’ll find an Include tag <?php get_header(); ?> that grabs the contents of header.php in your template directory and displays them on the screen. The header.php file starts out like every good XHTML file should; with a DOCTYPE declaration that provides the document structure to the web browser. In this case, the document is declared as XHTML Transitional and is served to the browser as such. After the DOCTYPE comes a series of meta tags and link tags. The meta tag specifies the character encoding of the document and the link tags reference the stylesheet, RSS Feed, and the Pingback function. So far so good.

Next you’ll find code that is specific to the Default template which provides style instructions for images such as the header and footer throughout the page. If you plan on modifying the template and adding a header image of your own, keeping this section of the code is not necessary. If you plan on leaving the header the way it is, it’s best not to delete anything here. Once you get past the style declaration, the real bulk of the page begins. The body tag starts the page that we see on screen, shortly followed by <div id="page"> </div>. This serves as a ‘wrap’ for the entire document and is concluded further on down the road in footer.php. But let’s not get ahead of ourselves. At this point, it’s just best to know that this is the container that holds our site structure together.

After the ‘wrap’, you’ll see another section starting with <div id="header"> </div>. In the template, this is where your header image and ‘home’ link are located. As I said above, if you plan on keeping the header the way it is, this bit of code wrapped around the h1 tags is necessary for the section to work properly. The reference to <?php echo get_settings('home'); ?> calls the settings found in the admin section and places your blog name inside of the anchor link within the header. The reference to <?php bloginfo('description'); ?> pulls your default description from the ‘Options’ page and places it in that spot. Now that you have a better understand of what the code is doing, let’s look at ways in which to customize it to meet your needs.

Navigating the Pages

For some reason, I’ve run into a lot of folks who think that the WordPress template files are set in stone and that you shouldn’t add or subtract from them because you run the risk of breaking something. It’s true, there are sections of code that need to remain intact for the page to work properly, but think of these PHP template files as regular XHTML files and you will find that you’ll be able to start doing more and more without ruining any of the structure.

Ok, moving on. We are all set with the header and everything looks good. However, if we want to add something like horizontal navigation so that our users can find their way around the Pages we have created, then we will have to make changes to the code just below the <div id="headerimg"> </div>. So how do we do that? Let’s take a look at a more recent WordPress theme.

One of the most useful bits of navigational code can be seen in the K2 theme, an improved version of the very popular WordPress theme, Kubrik. This code takes the pages that you make in the admin section and turns them into a fully customizable, horizontal unordered navigation list. It reads as follows:

1
2
3
4
5
6
7
8
<ul class="menu">
<li class="<?if (((is_home()) && !(is_paged())) or (is_archive()) or (is_single()) or
(is_paged()) or (is_search())) { ?>current_page_item < ?php } else { ?<page_item< ?php } ?>">
<a href="<?php echo get_settings('home'); ?>">Blog</a></li>
 
<?php wp_list_pages('sort_column=menu_order&depth=1&title_li='); ?>
<?php wp_register('<li style="position: absolute; right: 0px;">',''); ?>
</ul>

Wow. I know what you’re thinking. That looks like a jumbled mess. But it really isn’t, it’s actually pretty easy to understand if you break it down a little. Without getting too complex, the code is an unordered list that looks to see if certain values are met within the page. If those values are true, such as if you are on the home page and not on any other pages, it sets the class of the first li to current_page_item because you are indeed on the home page. Every other list item is then classified as page_item. If you look at my navigation bar above, you’ll see that the ‘home’ navigational anchor is underlined to let you know where you are within the site. I am able to assign the current_page_item class a value in my CSS file that makes it stand out from the other list items; a useful usability tool for people trying to navigate your site.

There may also be times when I need to manually enter the value of the header, perhaps on a very customized template page. No problem. I simply take out the PHP and replace it with semantic XHTML markup that the PHP would have generated.

1
2
3
4
5
6
7
8
9
<ul>
<li class="current_page_item"><a href="http://www.45royale.com">home</a></li>
<li class="page_item"><a href="/profile/" title="profile">profile</a></li>
 
<li class="page_item"><<a href="/archives/" title="archives">archives</a></li>
<li class="page_item"><a href="/portfolio/" title="portfolio">portfolio</a></li>
<li class="page_item"><a href="/contact/" title="contact">contact</a></li>
 
</ul>

Both of these examples can be placed inside of a container like <div id="navigation"> </div> and are fully customized via your stylesheet. The header.php file ends with an <hr />, breaking up the header and the next file that is called in. Now let’s move on to something a little more complex.

The nuts and bolts of your site

After the header has finished loading by means of the include tag <get_header (); ?> on Line 1, the next thing that loads is the content. There are several things that happen here, and I will try to explain them the best way possible. Here is what we have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<div id="content" class="narrowcolumn">;
<?php if (have_posts()) : ?>
 
<?php while (have_posts()) : the_post(); ?>
 
<div class="post" id="post-< ?php the_ID(); ?&gt">
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to
<?php the_title(); ?>"><?php the_title(); ?></a></h2>
 
<small><?php the_time('F jS, Y') ?><!-- by <?php the_author() ?> --></small>
 
<div class="entry">
<?php the_content('Read the rest of this entry'); ?>
</div>
 
<p class="postmetadata"&gtPosted in <?php the_category(', ') ?> |
 
<?php edit_post_link('Edit', '', ' | '); ?>
<?php comments_popup_link('No Comments', '1 Comment', '% Comments'); ?></p>
</div> < -- END OF POST -->
 
<?php endwhile; ?>
 
<div class="navigation">
<div class="alignleft"><?php next_posts_link('Previous Entries') ?></div>
 
<div class="alignright"><?php previous_posts_link('Next Entries') ?></div>
</div>
 
<?php else : ?>
 
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
 
<?php include (TEMPLATEPATH . "/searchform.php"); ?>
 
<?php endif; ?>
 
</div>
 
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Again, this may look like your screen had one too many drinks and vomitted a little in its mouth, but trust me, it’s all decipherable. I will go line by line and explain this code in more detail.

Line 2
1
<div id="content" class="narrowcolumn"></div>

This is the main div that holds the contents of your post.

Line 3
1
<?php if (have_posts()) : ?>

This is the beginning of The Loop. This line says if you have posts to display, go on to the next line.

Line 4
1
<?php while (have_posts()) : the_post(); ?>

This Template tag tells WordPress to continue to display posts as long as there are posts to display. The crucial part of this line of code is the while declaration which is a PHP function that keeps looping until a condition is no longer true. We’ll finalize this further down in the code.

Line 5
1
<div class="post" id="post-<?php the_ID(); ?>"></div>

This line of code is the div that contains the words of the post. This differs from <div id="content" class="narrowcolumn"></div> in that the ‘content’ div holds the ‘post’ div, and the ‘post’ div holds your written entry.

Line 6
1
2
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to
<?php the_title(); ?>"><?php the_title(); ?></a></h2>

Here WordPress displays the Permalink (the permanent place that this entry resides) and displays the title of the post wrapped within an h2 tag.

Line 7
1
<small><?php the_time('F jS, Y') ?><!-- by <?php the_author() ?> --></small>

The month (F), date (jS) and year (Y) that the post is written. The <!-- by is simply an XHTML comment that shows the author of the post when you View Source from the browser. You can keep it or get rid of it, it has no bearing on the functionality.

Line 8
1
2
3
4
5
<code>
<div class="entry">
<?php the_content('Read the rest of this entry'); ?>
</div>
</code>

WordPress displays the content of your post with the_content tag. This tag will display the entire entry unless you have included a <!--more--> break when you wrote the post. If you have, 'Read the rest of this entry' will show up in place of the <!--more--> tag.

Line 9
1
2
3
4
5
<code>
<p class="postmetadata"&gtPosted in <?php the_category(', ') ?> |
<?php edit_post_link('Edit', '', ' | '); ?>
<?php comments_popup_link('No Comments', '1 Comment', '% Comments'); ?></p>
</code>

This line uses multiple WordPress Template tags to display information about the post. As you might expect, the_category displays the category that you've filed your post under. The edit_post_link is a quick link to editing your post while you are logged in as Administrator. ('Edit', '', ' | ') means that the word 'Edit' is displayed as a link back to the admin menu for that post, '' indicates a space and ' | ' is used as a divider between the edit link and the comments. And speaking of comments, comments_popup_link shows how many comments are associated with that post. 'No Comments' is displayed if there aren't any comments yet, '1 Comment' is displayed if there is one (1) commment available and '% Comments »' shows up when there is more than one (1) comment.

Line 10
1
<-- END OF POST -->

The final line of code in this section closes

Line 11
1
<?php endwhile; ?>

Remember when I said that the while loop would run until there were no more posts to display? Well this is the next line of code after the post information and it stops the loop when there aren't any posts left to display; either because you're at the end of the posts or you have chosen only to show a specific number per page in the Admin Reading Options.

Line 12
1
2
3
4
<div class="navigation">
<div class="alignleft"><?php next_posts_link('Previous Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Next Entries') ?></div>
</div>

Here we are using navigation to move back and forth between posts. Using the tags next_posts_link(); and previous_posts_link(); we can negotiate between newer and older posts. Pretty self-explanatory.

Line 13
1
<?php else : ?>

This piece of code closes the <php while (have_posts()) : the_post(); ?></php> statement at the beginning of the loop and then displays the next line of code.

Line 14
1
2
3
4
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
 
<?php include (TEMPLATEPATH . "/searchform.php"); ?>

This information is displayed inside of the <div id="content" class="narrowcolumn"></div> if there is an error and a post cannot be found. It also uses the TEMPLATEPATH include to display the search box so that you can do another search if you've came up empty handed the first time.

Line 15
1
<php endif; ?></php>

This is the final call that ends the display of your posts and The Loop.

Line 16

Closing div for <div id="content" class="narrowcolumn"></div> which ends the content display.

Line 17
1
<?php get_sidebar(); ?>

A WordPress Include tag that calls the sidebar.php file and displays it after the content.

Line 18
1
<?php get_footer(); ?>

A WordPress Include tag that calls the footer.php file and displays it after the sidebar.

My retinas are burning

Whew! That's quite a bit to digest all at once, I think that's enough for right now. As always I welcome your comments and input. Please let me know if there's anything I've missed, anything that doesn't make sense, or anything else I can help with. I hope this proves useful and again, I plan on making a series out of these WordPress posts so be on the lookout for more in the coming weeks. Until then, do some exploring and don't be afraid to dig in and get your hands dirty.

Update: The second part of this tutorial can be found here.

7 Responses to "The WordPress ‘Default’ Theme Demystified – Part One"

  1. This is great! I’ve always wanted to learn more about WP, and everything I know so far is from just playing around. It’s wonderful to have a simplified explanation of what everything does. Thanks so much, and I truly look forward to the rest of your WP series. Nice work.

  2. Very nice. I’m using Wordpress and are planning to use it for my own site. I’m looking forward to read more of your tutorials.

  3. This is definately a huge and great explanation! Thanks a lot for the details, and how to change the UI from the Default layout. I’m going to have to read that one really carefully, hehe. I’m currently moving, but I’m sure this first part will help out a lot!

    I was looking for the xhtml of Wordpress, and believed it should be in the index.php. Well, I do know that I have to look further then the length of my nose ;)

    Thank you again, and I’m looking forward to your next articles about Wordpress’ secrets.

  4. Fantastic, that was such an informative read and i can’t wait to see more. This is making me want to use wordpress more for an upcoming project.

  5. Great article, Wish I’d found something as conscise a month ago :- )

    As for sugestions, how about extending the database to create reklationships between posts, like ’see also’ or parent-child relationships? (Yea we want to CMS)

  6. Nice read!

    Andre SC – That would be quite a simple plugin to write, you would just need to abuse the post cats

  7. Hey everyone, thanks for your input. I’m glad the first part has been useful. I haven’t had time to work on the next write up yet, but hopefully this weekend or Monday of next week I’ll have something. I have a few ideas for articles, so it’s just a matter of finding the time.

    For Andre SC – there is a Related Posts plugin that I’ve used on other blogs I’ve set up. It simply requires you to make an edit to your MySQL database. In my experience, it works pretty well.

    Thanks again for the positive comments, it really is a motivator to write more.

Trackbacks & Pingbacks

  1. Complete Wordpress Theme Tutorial « Kolmex
Required
Required, but not shared

About the author

Get the feed Matt Downey

Matt is the Lead Designer at 45royale and is responsible for front-end design and web development.

Latest from Twitter

    Recent Comments

    • Nate Bird: Great hire! I look forward to what you will be able to put together now! 7 days 0 hours ago
    • Adam Little: Thanks for the comments everyone! We’re really excited about working with... 7 days 3 hours ago
    • John Williams: Congrats! Really solid design work. 8 days 1 hour ago

    Latest from Last.fm

    About the Studio

    45royale Inc. is a small web design and development studio near Atlanta, GA. It is run by the handsome and esoteric Matt Downey and Adam Little. This blog serves as an online file cabinet for our articles, interests and other things we find noteworthy.

    Subscribe to the Global Feed

    Browse Categories

    Flickr Stream

    1