Multiple WordPress Page Layouts in One Single Template

The Problem

Our client wants a medium-sized site he can edit using WordPress as a CMS. Some sections in the navigation will have subpages, while some will not. We’re going to need a conditional that checks for subpages, and if they exist, uses a two-column layout…

subnav

…but if they don’t exist, removes the sidebar and uses a full-width <div>…

subnav

Multiple layouts can always be achieved with custom page templates, but to keep things clean and economical, it’s much better to rely on one global template (“page.php”) if you can get away with it. So how will it work?

The Solution

The first bit of code will set the “children” variable and determine which <div> class will wrap the content:

<div class=<?php if($post->post_parent)
$children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0"); else
$children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
if ($children) { ?>"narrowcolumn"<?php } else { ?>"widecolumn"<?php } ?>>

The second bit of code inserts a sidebar if necessary:

<?php if ($children) { ?>
<div id="sidebar">
In this section:
<ul><?php echo $children; ?></ul>
</div>
<?php } else { ?>
<?php } ?>

Bonus Challenge

Almost done, but wait — our client now wants just the “Resources” page to have a third column containing a list of useful sites:

subnav

Here we’ll use the is_page conditional to insert the column while the wp_list_bookmarks function grabs the links:

<?php if (is_page('resources')) { ?>
<div id="sidebar-resources"><?php wp_list_bookmarks(); ?></div>
<?php } else { ?>
<?php } ?>

The Final Template Code

With a few conditionals, our “page.php” template is now much smarter and can handle a variety of layouts:

<?php get_header(); ?>

<?php if (is_page('resources')) { ?>
  <div id="sidebar-resources"><?php wp_list_bookmarks(); ?></div>
  <?php } else { ?>
  <?php } ?>

<div class=<?php if($post->post_parent)
  $children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0"); else
  $children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
  if ($children) { ?>"narrowcolumn"<?php } else { ?>"widecolumn"<?php } ?>>

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <div class="post" id="post-<?php the_ID(); ?>">
  <h2><?php the_title(); ?></h2>
  <div class="entry">
  <?php the_content(); ?>
  </div>
  </div>
  <?php endwhile; endif; ?>
  <?php edit_post_link('Edit this entry.', '<p>', '</p>'); ?>
  </div>

<?php if ($children) { ?>
  <div id="sidebar">
  In this section:
  <ul><?php echo $children; ?></ul>
  </div>
  <?php } else { ?>
  <?php } ?>

<?php get_footer(); ?>