index.php is a strictly required file. Its job is to render all of our theme’s front-end output.
Since index.php will render all of our pages (home, posts, categories, archives), it will do a lot of work. First, we need a head section that covers the basics of HTML.
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head><meta charset=”<?php bloginfo( ‘charset’ ); ?>”><meta name=”viewport” content=”width=device-width, initial-scale=1″><link rel=”profile” href=”https://gmpg.org/xfn/11″><?php wp_head(); ?>
</head>
This is standard HTML with one exception [wp_head()](<https://developer.wordpress.org/reference/hooks/wp_head/>):. wp_head is a core feature that allows WordPress and third-party plugins to insert code into the header without modifying the template files. This is called an action hook.
If you are familiar with HTML, you may notice that there is no <title> tag to output the page title. This is because WordPress can use the wp_head hook to dynamically insert the title.
Another use for wp_head is to enqueue styles (.css) and scripts (.js). There are good reasons to do this instead of hard-coding them, which we’ll discuss later.
Next, we have the body of the page: (more on this later)
<body <?php body_class(); ?>>
body_class() is a helper function provided by WordPress that will output a list of useful CSS classes that describe the page being displayed, for example:
class=”page page-id-2 page-parent page-template-default logged-in”
body_class() ; also accepts a parameter so that you can add your own classes, for example:
<body <?php body_class( ‘wide-template blue-bg’ ); ?>>
Next, we have the template title.
<header class=”site-header”>
<p class=”site-title”>
<a href=”<?php%20echo%20esc_url(%20home_url(%20’/’%20)%20);%20?>”>
<?php bloginfo( ‘name’ ); ?>
</a>
</p>
<p class=”site-description”><?php bloginfo( ‘description’ ); ?></p>
</header><!– .site-header –>
Here we use WordPress’ built-in template functionality to output the site title and description. We also use the helper function home_url() to link the site title back to the homepage.
Next is the page text: <div class=”site-content”> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <article <?php post_class(); ?>> <header class=”entry-header”> <?php the_title( ‘<h1 class=”entry-title”>’, ‘</h1>’ ); ?> </header><!– .entry-header –> <div class =”entry-content”> <?php the_content( esc_html__( ‘Continue reading →’, ‘my-custom-theme’ ) ); ?> </div><!– .entry-content –> </article><!– #post-## –> <?php // If comments are open or we have at least one comment, load up the comment template. if ( comments_open() || get_comments_number() ) : comments_template(); endif; endwhile; else : ?> <article class=”no-results”> <header class=”entry-header”> <h1 class=”page-title”><?php esc_html_e( ‘Nothing Found’, ‘my-custom-theme’ ); ?></h1> </header><!– .entry-header –> <div class=”entry-content”> <p><?php esc_html_e( ‘It looks like nothing was found at this location.’, ‘my-custom-theme’ ); ?></p> </div><!– .entry-content –> </article><!– .no-results –> <?php endif; ?> </div><!– .site-content –>
This is where it gets interesting (and a little complicated). Here we use an important WordPress feature, the Loop. The loop does the hard work of determining what page the user is on and what content should be displayed. It then returns a list of one or more “posts” that we can loop through and output the data using template functions.
If the loop returns no results, such as on a 404 page or a deleted post, we use the else operator to display a predefined message.
Without any surrounding code, the simplified loop looks like this:
if ( have_posts() ) : // check if the loop has returned any posts.
while ( have_posts() ) : // loop through each returned post.
the_post(); // set up the content so we can use template tags like the_title().
the_title(); // output the post title.
the_content(); // output the post content.
endwhile;
else :
echo ‘No Page Found’; // output an error message if there are no posts.
endif;
?>
Note: Since WordPress originated as a blog, many functions use the “Post” terminology even though they can return and output any type of content (posts, pages, custom post types).
After that, we have the footer, and all we need to do is close the HTML tag that was opened previously. There is another action hook, wp_footer(), that WordPress and plugins actively use to include scripts in the footer that are needed to render the page.
<?php wp_footer(); ?>
</body>
</html>
If you have been following along so far, you will have a fully functional WordPress theme that looks like this:
WordPress Basic Theme Theme Template Prototype
Our theme is still basic (it has no CSS) and lacks many features that users consider essential (sidebars, navigation, metadata, thumbnails, pagination, etc.), but it is a great start!
Let’s continue and see how we can improve it.