do_action_ref_array( 'pre_get_posts', WP_Query $this )

Fires after the query variable object is created, but before the actual query is run.


Description Description

Note: If using conditional tags, use the method versions within the passed instance (e.g. $this->is_main_query() instead of is_main_query()). This is because the functions like is_main_query() test against the global $wp_query instance, not the passed one.


Parameters Parameters

$this

(WP_Query) The WP_Query instance (passed by reference).


Top ↑

Source Source

File: wp-includes/class-wp-query.php

View on Trac


Top ↑

Changelog Changelog

Changelog
Version Description
2.0.0 Introduced.

Top ↑

More Information More Information

Top ↑

Targeting the right query Targeting the right query

Be aware of the queries you are changing when using the pre_get_posts action. Make use of conditional tags to target the right query. For example, its recommended to use the the is_admin() conditional to not change queries in the admin screens. With the $query->is_main_query() conditional from the query object you can target the main query of a page request. The main query is used by the primary post loop that displays the main content for a post, page or archive. Without these conditionals you could unintentionally be changing the query for custom loops in sidebars, footers, or elsewhere.

Example targeting the main query for category archives:

function target_main_category_query_with_conditional_tags( $query ) {
	if ( ! is_admin() && $query->is_main_query() ) {
		// Not a query for an admin page.
		// It's the main query for a front end page of your site.

		if ( is_category() ) {
			// It's the main query for a category archive.

			// Let's change the query for category archives.
			$query->set( 'posts_per_page', 15 );
		}
	}
}
add_action( 'pre_get_posts', 'target_main_category_query_with_conditional_tags' );

Top ↑

Default main query arguments Default main query arguments

The main query (object) already has some default properties set depending on the page request. For example, for single posts the $query->is_single property is set to true. This means you can’t simply change a single post or page query into an archive of posts query (or the other way around). To achieve this you’ll have to reset these properties in the query object itself. Unless you are intimately familiar with these settings and are willing to coordinate them yourself, it’s suggested that you replace the main query by using WP_Query in the page.php or single.php (child) theme template files.

Top ↑

A Warning About Conditional Functions A Warning About Conditional Functions

pre_get_posts runs before WP_Query has been set up. Some template tags and conditional functions that rely on WP_Query will not work. For example, is_front_page() will not work, although is_home() will work. In such cases, you will need to work directly with the query vars, which are passed to the pre_get_posts hook as an argument ($query in examples on this page).

Top ↑

Offsets & Pagination Offsets & Pagination

Using the offset argument in any WordPress query can break pagination. If you need to use offset and preserve pagination, please keep in mind that you will need to handle pagination manually. Read the codex article Making Custom Queries using Offset and Pagination for more information.

Top ↑

Basic Examples Basic Examples

Exclude Single Posts by ID From Home Page Exclude Single Posts by ID From Home Page

function exclude_single_posts_home($query) {
	if ( $query->is_home() && $query->is_main_query() ) {
		$query->set( 'post__not_in', array( 7, 11 ) );
	}
}
add_action( 'pre_get_posts', 'exclude_single_posts_home' );

Top ↑

Exclude Pages from Search Results Exclude Pages from Search Results

function search_filter($query) {
	if ( ! is_admin() && $query->is_main_query() ) {
		if ( $query->is_search ) {
			$query->set( 'post_type', 'post' );
		}
	}
}
add_action( 'pre_get_posts', 'search_filter' );

Top ↑

Only Display Search Results After Specific Date Only Display Search Results After Specific Date

function date_search_filter($query) {
	if ( ! is_admin() && $query->is_main_query() ) {
		if ( $query->is_search ) {
			$query->set( 'date_query', array(
				array(
					'after' => 'May 17, 2019', 
				)
			) ); 
		}
	}
}
add_action( 'pre_get_posts', 'date_search_filter' ); 

Top ↑

Change the number of posts per page by post type Change the number of posts per page by post type

function hwl_home_pagesize( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'movie' ) ) {
		// Display 50 posts for a custom post type called 'movie'
		$query->set( 'posts_per_page', 50 );
		return;
	}
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );


Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note 1 content
    Contributed by seabluetom
    
    /**
    *
    *		The Code below will modify the main WordPress loop, before the queries fired,
    *	to only show posts in the halloween category on the home page.
    *
    */
    	function sbt_exclude_category($query){
    		
    		if ( $query->is_home() && $query->is_main_query() && ! is_admin() ) {
    			
    			$query->set( 'category_name', 'halloween' );
    		}
    	}
    	add_action('pre_get_posts','sbt_exclude_category');
    
  2. Skip to note 2 content
    Contributed by johnjullies

    Include Custom Post Types in the homepage

    function add_custom_pt( $query ) {
      if ( !is_admin() && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post', 'the_custom_pt' ) );
      }
    }
    add_action( 'pre_get_posts', 'add_custom_pt' );
    

    Include in Search Results

    function add_custom_pt( $query ) {
      if ( !is_admin() && $query->is_main_query() ) {
        if ( $query->is_search ) {
          $query->set( 'post_type', array( 'post', 'the_custom_pt' ) );
        }
      }
    }
    add_action( 'pre_get_posts', 'add_custom_pt' );
    

    Replace ‘the_custom_pt’ with the name of your custom post type.

  3. Skip to note 3 content
    Contributed by saddamcrr7

    Example for how to universally adjust queries for an ‘event’ post type:

    function university_adjust_queries($query){
       if ( ! is_admin() && is_post_type_archive( 'event' ) && $query->is_main_query() ) {
            $query->set( 'meta_key', 'event_date' );
            $query->set( 'orderby', 'meta_value_num' );
            $query->set( 'order', 'ASC');
            $query->set( 'meta_query', array(
                array(
                    'key'     => 'event_date',
                    'compare' => '>=',
                    'value'   => date('Ymd'),
                    'type'    => 'numeric',
                )
            ) );
       }
    }
    add_action( 'pre_get_posts', 'university_adjust_queries' );
    

You must log in before being able to contribute a note or feedback.