Skip to content

Early-bird lifetime licence: $199 once, for the first 200 buyers only. See the offer

pre_get_posts

Lets you change a query's settings before it runs, such as posts per page, post types or order, without writing a new query.

  • Type Action
  • From WordPress
  • Since 2.0.0
  • Fired in wp-includes/class-wp-query.php

When it fires

pre_get_posts fires inside WP_Query after the query variables are set but before the database is queried. It runs for every WP_Query: the main query for the page, secondary loops, widgets, and queries in the admin area.

You get the query object itself, so anything you change with $query->set() takes effect straight away.

Parameters

Parameters
$queryWP_Query The WP_Query instance (passed by reference).

Example: Show only blog posts in search results

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

Good to know

  • Check ! is_admin() and $query->is_main_query() first, or you'll also change menus, widgets and admin lists.
  • Use the methods on the object you're given, such as $query->is_search(), rather than the global is_search(), which checks the main query.
  • Changing posts_per_page here, instead of running a new query in the template, keeps pagination working.

Move your snippets over this afternoon.

Importing changes nothing until you switch over, and your old shortcodes keep working.