We recently came across a need to exclude a set of custom posts from our WordPress search results page, based on a value set in the custom fields of those posts.

The pre_get_posts action hook allows you to alter the database query for a page before it is run. Here is how we accomplished it.

In our case, the custom posts that we are trying to exclude don’t change very often, so we wrapped the get_posts result using the transients API for performance reasons.

The pre_get_posts hook is very powerful and can have unintended consequences if you don’t setup your conditionals correctly to determine exactly when the query modifications will occur. In our case, we originally didn’t have the !is_admin() conditional set, and what ended up happening is that it broke our media library search capabilities, since the media library also uses a search query.

We also ran in to a problem with a competing function that was also hooking in to pre_get_posts and setting its own posts__not_in parameter. Since that function ran after this one, it was overwriting the array of posts that we were trying to exclude. There are two approaches to address this. In our case, we simply consolidated the two functions by adding the other post IDs we were trying to exclude with array_push. You could also grab the existing query parameters using $query->get('post__not_in) and merge the two arrays before you callĀ $query->set. The challenge with the approach is that you still have to be conscious of the order in which the function execute.

My recommendation is that you consolidate your functions that alter your database queries using pre_get_posts, since altering the query in similar ways with multiple functions may very well lead to unintended results.

Latest Developer Blog Articles

Job Listings on GeekWork

Find more jobs on GeekWork. Employers, post a job here.