Excluding Page IDs from a Custom Query

Available on the DailyBlogTips website is a theme called StudioPress_Red. The theme uses a custom query to list the pages in the site navigation while applying a ‘current page’ class for styling the nav bar. The navigation code sets up a nav scheme with the traditional ‘Home’ button followed by the listing of pages. This works out just fine for the typical blogger who has his blog as his home page. It breaks down a bit, however, for the blogger who wants to set one of her static pages as the Home page, since she will then have both the ‘Home’ button as well as the selected page’s button showing in the nav bar. Typically, with the wp_list_pages function, you can simply add an exclude parameter to hide any pages you don’t want to show. With the StudioPress_Red theme, however, it not quite that straightforward.

Below is the block of navigation code from the header.php file. Line 47 (highlighted) is the line of interest that needs to be modified in order to exclude the appropriate pages from the nav bar:

<div id="nav">
<?php function get_the_pa_ges() {
  global $wpdb;
  if ( ! $these_pages = wp_cache_get('these_pages', 'pages') ) {
     $these_pages = $wpdb->get_results('select ID, post_title from '. $wpdb->posts .' where post_status = "publish" and post_type = "page" order by ID');
}
  return $these_pages;
 }

 function list_all_pages(){

$all_pages = get_the_pa_ges ();
foreach ($all_pages as $thats_all){
$the_page_id = $thats_all->ID;

if (is_page($the_page_id)) {
  $addclass = ' class="current_page"';
  } else {
  $addclass = '';
  }
$output .= '<li' . $addclass . '><a href="'.get_permalink($thats_all->ID).'" title="'.$thats_all->post_title.'"><span>'.$thats_all->post_title.'</span></a></li>';
}

return $output;
 }
?>
<ul>
<?php

if (is_home()) {
  $addclass = ' class="current_page"';
  } else {
  $addclass = '';
  }
echo "<li" . $addclass . "><a href='" . get_option('home') . "' title='Home'><span>Home</span></a></li>";
echo list_all_pages();?>
</ul>

<div class="cleared"></div>
</div> <!-- Closes Nav -->

What line 47 is doing is talking to the WordPress database and retrieving all published pages by their ID numbers and returning the titles of those pages to the navigation list, sorted by the pages’ IDs. In order to exclude certain pages from the list, a new parameter
needs to be added to line 47 to tell function to skip a page that’s set as the Home page. Unfortunately, even the WordPress Codex doesn’t provide any real documentation for page exclusions in a custom query, so you have to know your WordPress core and MySQL syntax to make it work.

Prior to WordPress 2.7, post ID numbers were saved to the database under the post_id field. From WordPress 2.7 and on, post_id was changed to just ID. So, in order to exclude the Home page ID from our custom query, we have to add and ID !="##" to line 47, where ## is the ID number of the page you want:

<div id="nav">
<?php function get_the_pa_ges() {
  global $wpdb;
  if ( ! $these_pages = wp_cache_get('these_pages', 'pages') ) {
     $these_pages = $wpdb->get_results('select ID, post_title from '. $wpdb->posts .' where post_status = "publish" and post_type = "page" and ID != "##" order by ID');
   }
  return $these_pages;
 }

 function list_all_pages(){

$all_pages = get_the_pa_ges ();
foreach ($all_pages as $thats_all){
$the_page_id = $thats_all->ID;

if (is_page($the_page_id)) {
  $addclass = ' class="current_page"';
  } else {
  $addclass = '';
  }
$output .= '<li' . $addclass . '><a href="'.get_permalink($thats_all->ID).'" title="'.$thats_all->post_title.'"><span>'.$thats_all->post_title.'</span></a></li>';
}

return $output;
 }
?>
<ul>
<?php

if (is_home()) {
  $addclass = ' class="current_page"';
  } else {
  $addclass = '';
  }
echo "<li" . $addclass . "><a href='" . get_option('home') . "' title='Home'><span>Home</span></a></li>";
echo list_all_pages();?>
</ul>

<div class="cleared"></div>
</div> <!-- Closes Nav -->

This tells the query to find all published pages that don’t have an ID of ## and return those page titles for display in the nav bar. Since I don’t work with the way WordPress communicates with the database very often, it took me a couple of hours of (nearly futile) research and experimentation to figure out what would work here. Hopefully you’ll find this information useful.

6 thoughts on “Excluding Page IDs from a Custom Query”

  1. really appreciate you posting this article… helped me out in a big way. (saved tons-o-time)

    and if it's helpful, you can continue excluding other pages with these types of templates:
    and ID != "373" and ID != "374" and ID != "375" and ID != "376" etc., etc.

    not completely elegant, but it works.

    sharing your post twitter… paying it forward!

    =)
    thanks again and cheers,
    //dave
    My recent post Welcome to Daveworks Web Development Website Design and Development Specialists for Small Businesses

    1. This post is nearly two years old, and the WordPress core has changed quite a bit since then. Unless StudioPress has been updated to work with the most recent iterations of WordPress, then I'd suggest finding a new theme or crafting a new one from the WordPress TwentyTen or TwentyEleven themes.

Have anything to add to the conversation?