pre_get_posts for exclude category

This code works perfectly

function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-1' );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );

But this code does not work at all

$caid = "-1";
function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', $caid );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );

Related posts

Leave a Reply

2 comments

  1. $caid is unknown inside the function, unless declared global.

    $caid = '-1';
    function exclude_category( $query ) {
        global $caid;
        if ( $query->is_home() && $query->is_main_query() ) {
            $query->set( 'cat', $caid );
        }
    }
    add_action( 'pre_get_posts', 'exclude_category' );
    

    // Edit
    Do you need the variable outside the function at all? If not, just move it inside the function, then you can ommit the global.

    PHP: Variable scope

  2. You can as well use closures in PHP:

    $catid = "-1";
    
    $excludeCategory = function ($catid)
    {
        return function ($query)
        {
            if (
                $query->is_home() 
                && $query->is_main_query()
            ) {
                $query->set('cat', $catid);
            }
        };
    };
    
    add_action('pre_get_posts', $excludeCategory($catid));
    

    This is a function returning a function. Therefore you can pass in the catid as a parameter at the time when you register the pre_get_posts action.