I have this code for the loop, and I need to exclude a category 4 from this loop. Any suggestions on how to achieve this?

Code that starts the loop

 <?php if(have_posts()): ?>

    <ol class="item_lists">

        $end = array(3,6,9,12,15,18,21,24,27,30,33,36,39,42,45);
        $i = 0;

        while (have_posts()) : the_post();
           global $post;

you could use wp_parse_args() to merge your arguments into the default query

// Define the default query args
global $wp_query;
$defaults = $wp_query->query_vars;

// Your custom args
$args = array('cat'=>-4);

// merge the default with your custom args
$args = wp_parse_args( $args, $defaults );

// query posts based on merged arguments

although, i think the more elegant route is using the pre_get_posts() action. this modifies the query before the query is made so that the query isn't run twice.

check out:


based on that example to exclude category 4 from the index i'd put this in your functions.php:

add_action('pre_get_posts', 'wpa_44672' );

function wpa_44672( $wp_query ) {

    //$wp_query is passed by reference.  we don't need to return anything. whatever changes made inside this function will automatically effect the global variable

    $excluded = array(4);  //made it an array in case you  need to exclude more than one

    // only exclude on the home page
    if( is_home() ) {
        set_query_var('category__not_in', $excluded);
        //which is merely the more elegant way to write:
        //$wp_query->set('category__not_in', $excluded);
  • Upvote to Helga as she mentioned pre_get_posts first. – Brad Dalton Sep 4 '14 at 5:33
  • 1
    instead of 'category__not_in' or 'category__in', you could use 'cat' and use a string as value e.g. '2,-4'. this way, not only the specified category would be included/excluded, but also its children. – honk31 Jun 6 '19 at 14:01

From your functions file

function remove_home_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-4' );
add_action( 'pre_get_posts', 'remove_home_category' );

This code alters the query before the actual query is run so is the most efficient hook to modify the loop in this case.

  • 1
    And why would you do that :-) – Pieter Goosen Sep 3 '14 at 15:59
  • Might be wrong but exclude from home loop? – Brad Dalton Sep 3 '14 at 19:17
  • Was actually hinting on you dumping code without proper explanation :-) – Pieter Goosen Sep 4 '14 at 4:23
  • Fair enough. Updated my answer and thanks for the reminder @goose! – Brad Dalton Sep 4 '14 at 5:31

Adam is right. In addition, for pagination to work, you need to have something more like so:

<?php query_posts('post_type=post&paged='.$paged.'&cat=-4');  ?>

Before the line

<?php if(have_posts()): ?>

Insert something like this

<?php query_posts($query_string . '&cat=-4'); ?>

This excludes the category with Category ID 4. As seen here

  • it does in fact remove the posts from that category but it's a kind of a portfolio on the users page, and now the pagination is broken on page 3. – jimilesku Mar 6 '12 at 23:50
  • I also have this custom made in the theme_setup.php: $newrules["user/({$author->nicename})/(portfolio)/?$"] = 'index.php?author_name=$matches[1]&baction=$matches[2]'; $newrules["user/({$author->nicename})/(portfolio)/page/?([0-9]+)/?$"] = 'index.php?author_name=$matches[1]&baction=$matches[2]&paged=$matches[3]'; – jimilesku Mar 6 '12 at 23:51
  • the pagination appears, and I can click it, but the page 2 ahs the same posts as page 1, and page 3 shows 404 error? Pls help :) – jimilesku Mar 7 '12 at 0:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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