WP_Query Readability Improvements (For Maintenance)

June 12, 2017

Working with WP_Query, especially when you’re doing some custom work outside of the usual “get some posts and display them on a template” can be powerful. This is especially true of some of the advanced arguments (like using WP_Meta_Query, for example).

It’s also kind of nice that setting up the process has a standard way of doing things. Namely:

But if you get to where you’re doing any advanced work such as working with a custom post type from a third-party solution, having to sideload media, determine if something exists before actually doing any work with it, then it can be a little more complicated to work with, can’t it?

I’ve found that, like with anything in programming, breaking it down into much more readable modules (or functions or pieces or whatever you’d like to call them) can make it much easier to work with.

So here’s one way that I go about working to make WP_Query readability improvements in a variety of the stuff I’ve done lately.

WP_Query Readability Improvements

Before walking through any example, it’s worth pointing out that there are some things that the way WP_Query is setup that we can’t do.

For example, once the query is instantiated, we may not be able to do much more advanced things with it (I mean, setting up any unit testing that doesn’t require WordPress core is going to be impossible).

This is the face of one who can’t follow your code.

With that said, here’s an example of how it can look when you start out and then how it can be refactored to have smaller functions each of which are more intentional than one long method.

An Example

For this post, let’s say I need to query the database for all published posts and posts and I want to order them by the ID.

Next, I want to determine if some third-party tool as assigned some metadata to it that corresponds to a template that I can later programmatically assign given a theme that I have.

Perhaps the initial version of the code might look something like this:

That’s a lot of code to do quite a bit of work for one function. At the very least, it lays out everything that needs to happen, doesn’t it?

Before reading any further, note the mapping array is just an example but the keys represent the meta key for mapping it, and that helps us to map defining the _wp_page_template value when it comes time to map it to actual WordPress template files.

So how can this be broken down?

1. Kick the Whole Thing Off

The first thing we want to do is create a function that sets the entire thing into motion. There are some ways that you can choose to do this.

But as you can see, there are still helper functions that need definitions. Things like the ability to get the template ID, the template name, and ultimately assign the template.

Note, however, that if any of the helper functions don’t return a useful value, then we continue with the loop. This is necessary if for not other reason than to make sure that we aren’t trying to map templates that don’t exist (but I find it also makes it a bit easier to read).

4. Find the File to Which the Template ID Maps

Next, a small function can be used to look at the third-party template ID and determine if we can map this value to the pages that exist in our database.

5. Grab the Template Name

Here’s the thing: We’re either going to return the name of the template, or we’re going to return a null value. Again, this is so that we can determine if we need to continue with the loop of assigning templates or not.

6. Assign the Template

Finally, we can grab the ID of the template as provided by the third-party and use that to map to the file we have included with our work as outlined earlier in the post:

Join the conversation! 5 Comments

Since we’re using WP_Query, we really need to be using wp_get_postdata(). There are a few places that you may choose to place it, but I’ve opted to place it outside the loop. I’ve updated the gist in the three section to address this.

Thanks Tom. I’ve always wondered if we didn’t have posts, if we still need to reset it. If that were the case it would make more sense at the end of map_page_templates() method. I’ve been using WP_Query for years, but haven’t dove into what wp_reset_query() is actually doing/preventing/helping.

The wp_reset_query() function restores the value of global $wp_query to the original main query, in case you’ve modified it (the main query, usually with query_posts() or messing up with globals). The $wp_query contains not only found posts (0 or many), but the entire WP_Query object. So yes, if you’ve replaced or modified the main query, use this function to revert it back to main query.

After restoring $wp_query it also calls wp_reset_postdata() function, which, in turn, restores the $post global variable to the current post in the main query. It should be used after custom WP_Query loops, because $posts->the_post() method in a custom loop replaces global post data with the data from current loop iteration. In the of the loop, the last post from that loop stays in globals. Calling wp_reset_postdata() after the custom loop brings back the post data from main loop back to globals.

Just Getting Started with WordPress?

I write a lot about WordPress development but if you're just getting started, I recommend checking out WPBeginner. They have free training videos, glossary, and more.

WPSessions hosts some of the best WordPress training you’ll find anywhere from many well-known speakers.

If there’s something you’d like to learn, and it’s not already covered here, it’s probably been covered at WPSessions. If you use the special link below you can watch your first session for free and get a steep discount on the full-access VIP membership.