WebCraft Tools

  • News
  • WordPress
    • WordPress Basics
    • WordPress Advanced
    • WordPress Performance
    • WordPress Security
    • WordPress Commerce
    • WordPress Troubleshooting
    • WordPress Themes
  • SEO and Analytics
WebCraft Tools › WordPress Advanced › How to modify the main WordPress query the right way

How to modify the main WordPress query the right way

Last updated on April 19, 2017 by Editorial Staff

Have you ever wanted to tweak what content WordPress served up on a particular portion of your website? Perhaps on your home page instead of the default 10 posts you only want to show 3 or maybe you want to exclude a particular category.

When I started in WordPress, and still even now, the way most people do it is by editing the WordPress loop in your themes template files. It’s usually done by adding a call to the query_posts function and a few arguments right before the while portion of the loop. There are a couple problems with this method though.

  1. It doesn’t support pagination
  2. You have to edit every template file where you want to modify the query

This makes this method a poor choice. Lot’s of themes and plugins use pagination and it’s great way to navigate your posts. Why break it? Also, anytime you upgrade your theme you will overwrite your changes. You could just copy those templates into a child theme but if you are going to copy all the structure over to a child theme, it’s not really a child theme anymore.

So what if I told you there was a much easier and cleaner way of doing this?

Introducing pre_get_posts

With pre_get_posts you can modify the main query anywhere on your site without ever touching a single file within your theme and pagination will continue to work as expected. pre_get_posts is an action hook that is called after the query variable object is created, but before the actual query is run. This means your changes are directly to the object itself and not during run time which offers a lot more control and flexibility.

Here is a sample of how it works. Comments are in the code.

[php]

// My function to modify the main query object
function my_modify_main_query( $query ) {
if ( $query->is_home() && $query->is_main_query() ) { // Run only on the homepage
$query->query_vars[‘cat’] = -2; // Exclude my featured category because I display that elsewhere
$query->query_vars[‘posts_per_page’] = 5; // Show only 5 posts on the homepage only
}
}
// Hook my above function to the pre_get_posts action
add_action( ‘pre_get_posts’, ‘my_modify_main_query’ );

[/php]

Pretty simple, right? Just place your own version of this code in a site functionality plugin or your child themes functions.php file and you’re done.

You can test for any condition you normally would and modify the query object directly for lean and mean content. For more info on this action and a more complete look at the object you are going to be modifying check out the WordPress Codex.

Tweet2
Pin
Share1
3 Shares

Filed Under: WordPress Advanced

Comments

  1. Marco says

    July 22, 2013 at 7:49 pm

    Great stuff, you have a broken link though.

    This is exactly what I needed, I just don’t want to do a WP_Query as I want to have a normal loop but modify the posts per page and that’s that. Thank you!!

    Reply
    • James Laws says

      July 22, 2013 at 8:05 pm

      Yeah, it’s a very useful tool. We use it all over the place including this website.

      Reply
  2. JB Christy says

    November 7, 2014 at 5:25 pm

    This is totally the right way to do this. Thanks!

    Reply
  3. JB Christy says

    November 7, 2014 at 6:15 pm

    BTW, shouldn’t the if statement be

    `if ( $query->is_home() && $query->is_main_query() ) { // modify only the main query on the homepage`

    The way you have it coded above I believe will modify all queries on the homepage, including queries in widgets.

    Reply
    • James Laws says

      November 20, 2014 at 8:29 am

      Yes, That is correct. I wrote this years ago and meant to come back an update but just forgot. This has been updated to reflect the is_main_query check. Thanks.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Site Links

  • Contact Us
  • Disclosure Statement
  • Privacy Policy

About WebCraft.tools

WebCraft.tools is your free resource for building, maintaining, and improving your WordPress website. Whether you are building your first site or have been building them for years, WebCraft.tools aims to provide you with tips, tricks, tutorials, and reviews to take your WordPress site to the next level.

© 2017 - 2021 · WebCraft Tools · Built by the WP Ninjas, LLC