I’ve registered a custom post type called “node”.
When I create a basic WP_Query to get posts of that type, it works just fine. Example:
$args = array(
'post_status' => 'publish',
'post_type' => 'node');
$query = new WP_Query($args);
This will get all published posts of type “node”.
However, as soon as I combine this with a search, nothing is returned. Example:
$args = array(
'post_status' => 'publish',
'post_type' => 'node',
's' => 'My search term');
$query = new WP_Query($args);
This will get nothing, although it should get several posts of type ‘node’ that contain ‘My search term’.
As far as I can see, the post types are automatically set to “post” and “page” as soon as I include the “s” parameter in $args. If I print out a var_dump of $query, it shows the following:
Without “s”:
object(WP_Query)
public 'query' =>
array (size=2)
'post_status' => string 'publish' (length=7)
'post_type' => string 'node' (length=4)
public 'query_vars' =>
array (size=63)
'post_status' => string 'publish' (length=7)
'post_type' => string 'node' (length=4)
...
With “s”:
object(WP_Query)
public 'query' =>
array (size=2)
'post_status' => string 'publish' (length=7)
's' => string 'My search term' (length=14)
'post_type' => string 'node' (length=4)
public 'query_vars' =>
array (size=66)
'post_status' => string 'publish' (length=7)
's' => string 'My search term' (length=14)
'post_type' =>
array (size=2)
0 => string 'post' (length=4)
1 => string 'page' (length=4)
...
So WordPress seems to override the post types as soon as a search is involved.
How can I fix that?
You are right, I tried it in a clean WordPress install and it works.
Seems like one of the plugins I use in my environment is hooking itself in one of the pre-query events.
Thanks!
On a stock WordPress installation, WP_Query will default to
post_type
='post'
.Consider this simple example:
It will result in the following query to be executed:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
THE BEST SOLUTION
The solution is to add a
post_type
argument set to'any'
. This way WordPress will automaticaly search among all types except revisions and types withexclude_from_search
set totrue
. Problem, by default, attachments are not excluded from search. As long as you don’t have apost_status
argument set to'inherit'
, you should not be annoyed because attachments always havepost_status
set to'inherit'
.This way the query will change to:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
If needed, you can exclude attachments from search by using this code:
I’ve just stepped in this, and such solution worked for me:
instead of
'post_type' => 'node'
try'post_type' => ['node']
I know this is a really old question but I came across this because I had the same problem. I can’t comment because of reputation, but I want to help people like @Stefano so you don’t have to go through all your plugins and check which one causes the change to the query.
For me it was a plugin called “Custom Search by BestWebSoft“. But it wasn’t the plugins fault, I just hadn’t ticked the box for my custom post type in its settings.