I'm currently using this loop:

if (is_single() || is_page() ) :
  if (have_posts() ) :
    while (have_posts() ) :

How can I exclude multiple pages within the loop?
For an example, I want to exclude pages example.com/music and example.com/contact.


I've done the way G.M provide, but my music and contact pages keeps loading after apply.

<?php if (is_single() || is_page() ) : if (have_posts() ) : $exclude_pages = array('music', 'contact'); while (have_posts() ) : if ( is_page() && ! empty($exclude_pages) && (
      in_array($post->post_name, (array)$exclude_pages) ||
      in_array($post->post_name, (array)$exclude_pages)
  ) ) continue; the_post(); ?>
<meta name="description" content="<?php the_content_limit(150)?>" />
// loop continues
<?php endwhile; endif; 
elseif (is_home() ): ?>
// loop continues

<?php endif; ?>

<?php if( is_page( 'music' )) { ?>
<meta property="og:image" content="" />
//loop continues
<?php } ?>

So to clarify: I'd like to exclude some meta tags that i'm generating via a loop in the header.php Now with my loop, all pages and post get affected by the loop. So I don't want the pages music and contact to have the same header tags from the loop in header.php.

  • Could you clarify where you want to exclude the pages? And also, if you could give some context as to how this loop code is being used, that would help me understand exactly what is going on. Is this a standard WP page, or some custom functionality? Thanks!
    – Andy Adams
    Aug 30, 2013 at 16:59
  • Still not clear: in which file are you using this code? It is in the page.php or somewhere else? If this loop the main or are you using query_posts to generate a custom loop? The loop in the header, how is generated? with WP_Query, query_posts or get_posts?
    – gmazzap
    Aug 31, 2013 at 15:45
  • No I'm not using this loop in page.php, I'm using it in the header.php (between <head></head>) file. What do you mean with how the loop is generated? The loop above is the complete loop code i've entered in the header.php file.
    – Eric
    Aug 31, 2013 at 17:45

2 Answers 2


An alternative way is putting the unwanted pages in an array. Useful for storing them in a option or in a serialized custom field.

$exclude_pages = array('music', 'contact');
// can be something like this: $exclude_pages = get_option('exclude_pages');

if ( have_posts() ) : while ( have_posts() ) : the_post();
  if ( is_page() && ! empty($exclude_pages) && (
      in_array($post->post_name, (array)$exclude_pages) ||
      in_array($post->post_title, (array)$exclude_pages)
  ) ) continue; // skip

  // the rest of your loop here


To also exclude some post type you can use:

$exclude_pages = array('music', 'contact');
$exclude_post_types = array('music', 'any_here');

if ( have_posts() ) : while ( have_posts() ) : the_post();
  if ( is_page() && ! empty($exclude_pages) && (
    in_array($post->post_name, (array)$exclude_pages) ||
    in_array($post->post_title, (array)$exclude_pages)
  ) ||
  ( is_single() && in_array(get_post_type(), (array)$exclude_post_types) ) ) continue;
  • please see edit above in my question
    – Eric
    Aug 31, 2013 at 14:37
  • thanks, your edited version works perfectly. One more question, if I want to exclude a post template like single-music, would I then need to place the '$exclude_pages = array('single-music');' after ' if (have_posts() ) :' ?
    – Eric
    Sep 2, 2013 at 11:09
  • @Eric see the edit
    – gmazzap
    Sep 2, 2013 at 12:03

is_page() will take a parameter for the page slug. That plus some logic operators should do it.

if (
  (is_single() || is_page())
  && (
    || !is_page('contact')

Note: it is very easy to get the logic wrong on these, and I didn't test that. It may not be quite right but I am sure it is close.

  • Why check for is_single() it never returns true for single page, if I'm not wrong. Maybe is_singular(), but why?
    – gmazzap
    Aug 31, 2013 at 7:05
  • is_single() is true for single post/CPT pages. is_singular() is true for single page and single attachment types as well as for single post/CPT pages. is_singular() could probably stand in for some of that logic but the question description is minimal and the code is truncated. I am not really sure what the OP wants. Your answer is certainly a reasonable one, @g-m
    – s_ha_dum
    Aug 31, 2013 at 13:38
  • Ah, ok. Problem is that, when I read cpt I always think it stands for custom post type. When I read page I always think at default page post type. So in my mind a cpt page does not exist only cpt post.
    – gmazzap
    Aug 31, 2013 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.