Using WordPress ‘pre_get_posts’ PHP action

The pre_get_posts WordPress PHP action allows you to modify the query object before the actual query is executed.

Usage

add_action('pre_get_posts', 'your_custom_function');
function your_custom_function($query) {
  // your custom code here
  return $query;
}

Parameters

  • $query: WP_Query, The WP_Query instance (passed by reference).

More information

See WordPress Developer Resources: pre_get_posts

Note: When 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.

Examples

Exclude a category from the main query

This code excludes posts from the ‘news’ category on the homepage:

add_action('pre_get_posts', 'exclude_news_category');
function exclude_news_category($query) {
  if ($query->is_home() && $query->is_main_query()) {
    $query->set('category__not_in', array(3)); // Replace 3 with the category ID you want to exclude
  }
}

Show only posts from a specific author

This code displays posts from the author with ID 1 on the main query:

add_action('pre_get_posts', 'show_author_posts');
function show_author_posts($query) {
  if ($query->is_main_query()) {
    $query->set('author', 1); // Replace 1 with the author ID you want to display
  }
}

Change the number of posts per page

This code changes the number of posts displayed per page to 5:

add_action('pre_get_posts', 'change_posts_per_page');
function change_posts_per_page($query) {
  if ($query->is_main_query()) {
    $query->set('posts_per_page', 5);
  }
}

Order posts by title

This code orders posts alphabetically by title on the main query:

add_action('pre_get_posts', 'order_posts_by_title');
function order_posts_by_title($query) {
  if ($query->is_main_query()) {
    $query->set('orderby', 'title');
    $query->set('order', 'ASC');
  }
}

Show only posts with a specific meta key and value

This code shows posts with a meta key ‘featured’ and value ‘yes’ on the main query:

add_action('pre_get_posts', 'show_featured_posts');
function show_featured_posts($query) {
  if ($query->is_main_query()) {
    $meta_query = array(
      array(
        'key' => 'featured',
        'value' => 'yes',
      ),
    );
    $query->set('meta_query', $meta_query);
  }
}