1. Code
  2. PHP

Mastering WP_Query: Actions and Filters

Scroll to top
This post is part of a series called Mastering WP_Query.
Mastering WP_Query: Related Functions
Mastering WP_Query: Properties and Methods

Welcome to third part of our series called "Mastering WP_Query". In the previous part, we went through 13 WordPress functions that are related to the WP_Query class. In this part, we will be reviewing WordPress hooks (filters and actions) that you can use in conjunction with WP_Query.

So, without further ado, let's begin!

WP_Query-Related Filters

In the "Filters Reference" of the Codex, there are 16 WordPress filters listed under the title "WP_Query Filters". In this section, we're going to talk about them. It will be a fairly quick section because most of the filters are about different "clauses" of a database query made by the WP_Query class.

We'll get back to them, right after going through the filters that are not related to the clauses.

Filtering the Number of Found Posts for the Query: found_posts

This filter allows you to change the number of found items without the limit that comes from WP_Query's posts_per_page argument.

This filter is particularly useful for creating custom pagination. Let's see what the Codex says:

For instance, if you are declaring a custom offset value in your queries, WordPress will NOT deduct the offset from the the $wp_query->found_posts parameter (for example, if you have 45 usable posts after an offset of 10, WordPress will ignore the offset and still give found_posts a value of 55).

Makes sense.

Filtering the Query to Run for Retrieving the Found Posts: found_posts_query

The number of found items is calculated with the SELECT FOUND_ROWS() command in MySQL. This filter lets you change this command to something else, in case you need to calculate the number of found items in a different way.

Filtering the Entire SQL Query: posts_request

If you want to change the completed SQL query, this is the filter you should use. It basically overrides the whole SQL query composed by the WP_Query class.

Filtering the Array the Query Returns: posts_results

If you want to alter the PHP array that WP_Query generates with the SQL query, you can use this filter. There's a neat example over on the Codex so you can see how it works.

(Please note that this filter handles the raw array that's generated from the SQL query.)

Filter the Array of Retrieved Posts: the_posts

Unlike posts_results, the the_posts filter waits for the array to be internally processed, meaning that the array would be checked against unpublished and sticky posts. Use this one if you don't want unpublished or posts in your array.

Filtering the Field List (and the SELECT Clause) of the Query: posts_fields

The SELECT clause of an SQL query determines which database fields will be selected from the resulting database rows, and this filter helps you filter it.

Filtering the LIMIT Clause of the Query: post_limits

The LIMIT clause of an SQL query sets the limitations to the query, and this filter helps you filter it.

Filtering the DISTINCT Clause of the Query: posts_distinct

The DISTINCT clause of an SQL query states that the query should return only different results, and this filter helps you filter it. Naturally, WP_Query does not return distinct results but when you use this filter with a function that returns "DISTINCT", the query will be adjusted to return only different results.

Filtering the WHERE Clause of the Query: posts_where

The WHERE clause of an SQL query is used to filter MySQL's SELECT, INSERT, UPDATE or DELETE statements, and this filter helps you filter this filter. While the WP_Query class does all the work needed to filter the results, you can take it a step further by using this filter.

Filtering the WHERE Clause of the Query After the Paging Is Calculated: posts_where_paged

This filter is an iteration to the posts_where filter, which you can use with paging queries.

Filtering the WHERE Clause of a Search Query: posts_search

Another iteration to the posts_where filter is this filter, which you can use to alter the WHERE clause of a query that's used to get search results in WordPress.

Filtering the JOIN Clause of the Query: posts_join

The JOIN clause of an SQL query allows you to work your SQL command within multiple database tables, and this filter helps you filter it. This is one of the advanced parts of MySQL, so I don't recommend using this filter unless you know very well how MySQL JOINs work.

Filtering the JOIN Clause of the Query After the Paging Is Calculated: posts_join_paged

Just as posts_where_paged is an iteration of posts_where, this is an iteration to the posts_join filter that works on paging queries.

Filtering the ORDER BY Clause of the Query: posts_orderby

The ORDER BY clause of an SQL query arranges the ordering of the query, and this filter helps you filter the order.

Filtering the GROUP BY Clause of the Query: posts_groupby

The GROUP BY clause of an SQL query makes the query return "grouped" results by a database field, and this filter helps you filter how to group the results.

Filtering All Clauses of the Query: posts_clauses

If you want to deal with all clauses at the same time, there's a filter for that, too: posts_clauses. This filter covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT, SELECT, and LIMITS clauses.

WP_Query-Related Actions

Now we've reviewed the filters related to WP_Query, let's move on to the other kind of hooks: actions.

Interfere With the Query Before It's Run: pre_get_posts

Before the query is parsed, you can interact with it (e.g. inject additional query variables) by using this action. Let's see a quick example from Tom McFarlin to learn how to exclude a category from the main loop:

1
<?php
2
3
function tutsplus_exclude_category( $wp_query ) {
4
5
    /*

6
     * Add the category to an array of excluded categories. In this case, though,

7
     * it's really just one.

8
     */
9
    $excluded = array( '-1' );
10
11
    /*

12
     * Note that this is a different, perhaps, cleaner way to write:

13
     * 

14
     * $wp_query->set( 'category__not_in', $excluded );

15
     */
16
    set_query_var( 'category__not_in', $excluded );
17
18
}
19
20
add_action( 'pre_get_posts', 'tutsplus_exclude_category' );
21
22
?>

Handle the Parsing of the Query: parse_query

Unlike pre_get_posts, which intervenes with the query before the query variables are set, the parse_query action handles the process after the query variables are set. Thus, you should use this action if you want to check the current variables and take action in accordance with them.

Modify the Post Object: the_post

The term the_action is a little bit confusing because it's the name of an action hook, a WP_Query-related function and also a method of the WP_Query class.

This action, as the Codex says, lets us modify the post object immediately after being queried and set up. Using this action, you can change the output directly. Let's see a quick example:

1
<?php
2
3
function tutsplus_featured_badge( $post ) {
4
5
    if ( is_single() && in_category( 'featured' ) ) {
6
        
7
        echo '<div class="featured-badge">' . __( 'FEATURED', 'tutsplus' ) . '</div>';
8
9
    }
10
11
}
12
13
add_action( 'the_post', 'tutsplus_featured_badge' );
14
15
?>

End of Part Three

Actions and filters are always a fun topic to talk and write about. (I know for a fact that my two series about WordPress actions and WordPress filters were fun to write and got a great reaction from our reader base.) I hope you enjoyed this part as much as I enjoyed writing it.

Want to add anything to the article? Shoot a comment in the comments section below. And if you liked the article, don't forget to share it with your friends!

See you in the next part, where we'll be talking about the properties and methods of the WP_Query class!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.