Part 7: Building a Layout for Posts and Pages and Custom Page Layouts


Now that we have index.php with a loop up and running, it’s time to create the more of our theme, including single.php, page.php, and a fullwidth page layout to boot, fullwidth-page.php!

We’re also going to learn about the template hierarchy and after getting a handle on this we’ll cover WordPress Generated CSS, so it’s easy to work with the HTML it generates.

Recommended Reading

In this tutorial we’re creating single.php which introduces more template tags, as well as modifying our loop, and then going over WordPress Generated CSS. Therefore you should

Template Hierarchy in a Nutshell

A WordPress theme will usually have some, or most of, the following template files:

  • single.php
  • page.php
  • category.php
  • tag.php
  • search.php
  • author.php
  • archive.php

And when you open a post WordPress looks for single.php, but what if you don’t have a single.php? What it boils down to is that if you’re trying to display a post, and there is no single.php file, it will default to using index.php.

In fact, it works this way across the board. There’s a flow chat courtesy of that goes shows it all and I strongly recommend keeping it bookmarked for quick reference.

Template Hierarchy in Practice

Even as early as now we can put this to the test. Open your site and view one of your posts, you’ll see that it’s based on index.php, most notably as the content available is only an excerpt.

template hierarchy in action

Creating single.php

single.php should have;

  • Post Title
  • Meta data
  • Tags, and
  • Comments

With this new knowledge under our belt and the expectations for this page, it’s time to get down to business. Create a new file called single.php.

The Basics

We’re going to need a loop, so to save repeating what we’ve already done, simply copy index.php across and make the following changes

  • Change the opening loop to while ( have_posts() ) : the_post();
  • Remove the_permalink from the post title
  • Change the_excerpt to the_content
  • Delete the “continue reading” button we made
  • Add in the_tags in its place
  • Delete the endwhile before the pagination
  • Change previous_posts_link( '« Previous Page' ) to previous_post_link( '%link' )
  • Change next_posts_link('Next Page »') to next_post_link( '%link' )
  • Add in a call to the comments using comments_template in its own section below the posts navigation
  • Delete the endif after posts navigation and replace it with endwhile

The code for single.php is below, feel free to refer to it to help track the changes.

<?php get_header(); ?>
<div class="container">
  <?php get_sidebar(); ?>
  <div class="span9">
  <?php while ( have_posts() ) : the_post(); ?>
  <section <?php post_class(); ?>>
    <div class="page-header">
        <?php the_title(); ?>
        By <?php the_author_posts_link(); ?>,
         in <?php the_category( ', ' ); //separated by a commma and space ?>,
         on <?php the_time( 'F j, Y' ); //DD Month, YYYY format dates ?>
    <?php the_content(); ?>
  <section class="tags">
    <?php the_tags(); ?>
      <ul class="pager">
        <li class="previous">
          <?php previous_post_link( '%link' ); ?>
        <li class="next">
          <?php next_post_link( '%link' ); ?>
    <!-- BEGIN COMMENTS -->
      <?php comments_template(); ?>
    <!-- END COMMENTS -->
  <?php endwhile; ?>
<!-- closing .container -->
<?php get_footer(); ?>

In doing the above, we have:

  1. Simplified the loop. We already know that we already have the post
  2. Removed the permalink from the title because it’s redundant for a post to link to itself
  3. Changed from an excerpt to the whole content, as that’s what we want to see
  4. Removed the continue reading button because we’re already on the post
  5. Used the_tags to display the tags that the post has
  6. Added navigation to go to the next or previous post. Note the parameter %link, as without it a « or » would display in the middle of the page, and
  7. Added a call to pull the comments in

A walk in the park! Though our single.php is functional, it’s quite basic. You can customize this further with different functions and add css if you need to. Here’s an obligatory screenshot of ours

completed single.php showing tags and post to post nav

Creating page.php

Just as before create your page.php file, then paste the contents of single.php straight into it. That’s it.

Without doubt, this is the easiest template file one can make. If you don’t believe me, let’s check out the page.php of WordPress’ TwentyTwelve theme.

 * The template for displaying all pages.
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages
 * and that other 'pages' on your WordPress site will use a
 * different template.
 * @package WordPress
 * @subpackage Twenty_Twelve
 * @since Twenty Twelve 1.0

get_header(); ?>

	<div id="primary" class="site-content">
		<div id="content" role="main">

			<?php while ( have_posts() ) : the_post(); ?>
				<?php get_template_part( 'content', 'page' ); ?>
				<?php comments_template( '', true ); ?>
			<?php endwhile; // end of the loop. ?>

		</div><!-- #content -->
	</div><!-- #primary -->

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

Many themes now come with custom page layouts, such as ones for full width and contact forms. Creating a full blown custom page will be included in the advanced series of Couch to WP Pro, but we’re going to create a full width page layout now as a teaser.

Creating a Full Width Page

For our full width page layout we essentially need to remove the sidebar and increase the width of the content area, therefore we need to be aware of what’s actually in the sidebar. In Flatstrap there are two particulars to be aware of.

  1. Flatstrap is a 12 column layout, the sidebar consumes 3, therefore we need to make up for that space.
  2. sidebar.php has the opening row div: <div class="row">

With these in mind, create a file called fullwidth-page.php and paste the contents of page.php in it and make do the following:

Change the opening header tag to

  /*Template Name: Full Width Layout*/
 get_header(); ?>

Replace with <div class="row">, and immediately below
Change <div class="span9"> to <div class="span12">

Save the file, and jump into your Dashboard and edit a page, and you should see our full width layout is now available.

full width page layout now available

Update your page with the new layout selected, and check it out to make sure it’s working!

full page layout


WordPress Generated CSS

For the most part, you can make WordPress use whatever CSS classes and ids you like. But there’s a few classes that WordPress will automatically add to images, and though we can get around it, it’s definitely easier to support them. Plus if you intend on submitting your theme for sale it’s required that they are supported as the end user needs to be able to decide how to align their content. It also means that the experience of using WordPress can remain consistent across themes.

/*WordPress Generated Styles*/



/*These next two do not need styling, 
but need to be present in the stylesheet*/

How do images look at present?

As you can see, I’ve opened the “Image Test” post and they look absolutely dreadful.

how images look currently without supporting styles

We need to fix this, and to do that we need to write our own CSS for the first time in the series. Rather than make any changes to what Bootstrap includes, we’ll create style.css in the assets/css folder, and queue it just like we did inPart 4.

When you have that ready, here’s the css to add.

	clear: both;
	display: block;
	margin-left: auto;
	margin-right: auto;
	display: inline;
	float: left;
	margin-right: 1em;
	display: inline;
	float: right;
	margin-left: 1em;

Really easy to do, and here’s how it looks in our theme.

images with alignment css

If you’d prefer the images and titles to not overlap (my preference) you can remedy it with the following

.post p { /* stops images and headers from overlapping*/
	display: inline-block;

Captioned Images

Here’s how the theme currently displays captioned images.

captioned image with no styles

You can’t really tell that the caption is anything other than text, there’s no way to differentiate it from the rest of the page. Here’s the CSS I’ve gone with

	background: #f2f2f2;
	padding: 3px;
	max-width: 100% !important;
.wp-caption img {
	width: 100%;
/* using !important is not ideal, but large images will not be constrained otherwise*/
	margin: 5px;
	font-style: italic;

And a screenshot.

captioned image with styles

Winding Up

That’s really all to do for now, if you wanted to push the boundaries and carry on building bits and pieces into your page, or changing the layout, or something else, do so! Especially if you’re using Flatstrap, check out the documentation and see how you can spice up the layout with what it provides.

Coming up next we’re going to tackle the comments. We’ve got the tag in there ready for us, but it is a different kind of complexity compared to what we’ve just done, so take a break if you need it, and hit the comments when you’re ready.

Table of Contents

Share on Facebook Back to Top

Speak up! Let us know what you think.