I’m trying to display all posts and only certain custom posts on the homepage.
Essentially: (post_type = post) OR (post_type = exhibition AND featured = 1)
I’m stuck with the actual implementation though.
pre_get_posts
and $query->set(...);
don’t seem to allow logic on the post_type
, it seems you can only set (post OR exhibition) AND (featured=1)
.
I’d rather not have to set featured=1
on every single post.
Any help appreciated.
You can’t specify OR
or AND
on arbitrary WP_Query
arguments. Meta and Taxonomy queries let you specify OR
or AND
for those queries, but other arguments are all combined (post_type
is a property of the post, not meta, so a meta query won’t help). Refer to the documentation for each of the possible arguments and how to use them.
You’ll see that some arguments support an Array as a value, like post_type
, so you can pass 'post_type' => ['post', 'exhibition']
and it will get both exhibition
and post
posts.
However when you’re doing this you can’t specify that another argument or meta query only apply to one of the post types.
If the posts are going to be displayed separately, then you could just perform 2 queries. Otherwise you will need to query the database directly with wpdb
. That would look something like:
global $wpdb;
$results = $wpdb->get_results(
"SELECT
posts.*
FROM
$wpdb->posts posts
LEFT JOIN
$wpdb->postmeta ON
( posts.ID = postmeta.post_id AND postmeta.meta_key = 'featured' )
WHERE
posts.post_type="post" OR
( posts.post_type="exhibition" AND postmeta.meta_value="1" )
"
);
I haven’t tested it, but that’s the rough idea. You’d need to add SQL for the posts count and any ordering as well.
There’s also the posts_where
and posts_join
filters you could use to modify the existing query for the posts. That’s a little bit more involved, but if you need to modify the main query or are relying on other WP_Query
arguments and don’t want to have to rewrite their SQL then you should use those filers.