Alter a query in WordPress with pre_get_posts

Last modified March 10, 2019
.* :☆゚

Say you want to display ten posts on the blog page, and twenty ’events’ on a custom post type archive. Changing the settings isn’t enough, as the number set in the admin affects all post types globally.

This snippet is a handy way to easily customise the output of all queries using one powerful function.

Just add this snippet in your functions.php file and change the arguments to your desired values. You can use any of the standard WP_Query arguments with this function.

<?php 

add_action( 'pre_get_posts', function ( $q ) {
    //check if the page is not an admin page, and is the main page query on the home(blog) page
    if( !is_admin() && $q->is_main_query() && $q->is_home() ) {
        $q->set( 'posts_per_page', 10 ); //set your post limit
        $q->set( 'orderby', 'comment_count' ); // then set other args as you like
    }

    //check if the page is the events post type archive
    if( !is_admin() && $q->is_main_query() && $q->is_post_type_archive( 'events' ) ) {
        $q->set( 'posts_per_page', 20 ); //set your post limit
        $q->set( 'orderby', 'meta_value' ); //this example is sorting the posts by a custom meta field, called 'start_date'.
		$q->set( 'meta_key', 'start_date' );
    }

    //add more statements below if needed
});