(Moderator’s note: The question’s original title was: “Custom query: Show custom post types plus custom post type with post meta on blog homepage”)
I’m in need of help with a custom query. I have three custom post types: “News”, “Events”, “Stories”. On the main blog page, only News and Events will show. The client can choose to mark a Story as News using features of the plugin Verve Meta Boxes. If a Stories post has a post meta key of 'mark-as-news'
then the that post should display on the main blog page as well.
So what I need help with writing is this:
If Stories has post meta
'mark-as-news'
then the main blog
page will display custom post types
News and Events, as well as Stories,
in descending order.
Can someone please assist?
Thanks!
Edit:
Perhaps a better way of wording this would be?:
Show custom post types News and
Events, and if there is the key
'mark-as-news'
for post_meta
, show
Stories.
Hi @webcodeslinger:
Here’s what a basic MySQL query for loading News and Events would look like (this is greatly simplified from what WordPress actually does):
SELECT * FROM wp_posts WHERE post_type IN ('news','events')
What you want instead is something like this (there are more performant ways to do this in MySQL but they are more complex in WordPress and for most sites you’ll never notice a difference):
SELECT * FROM wp_posts WHERE post_type IN ('news','events')
OR (post_type="stories" AND ID IN
(SELECT post_id FROM wp_postmeta WHERE meta_key='mark-as-news')
)
So…to add that extra SQL to your main loop’s query use a 'posts_where'
hook. You can put the following hook code into your theme’s functions.php
file (at the bottom of the file will do) or in one of the .php
files of a plugin if you are creating a plugin:
add_action('posts_where','yoursite_posts_where',10,2);
function yoursite_posts_where($where,$query) {
global $wp_the_query;
if (is_home() && $query===$wp_the_query) { // This means home page and the main loop
global $wpdb;
$where .= " OR ({$wpdb->posts}.post_type="actor" AND " .
"{$wpdb->posts}.ID IN (" .
"SELECT post_id FROM {$wpdb->postmeta} " .
"WHERE meta_key='mark-as-news')) ";
}
return $where;
}