Since news has no custom fields, you'll probably have better luck with this:
$args = array(
'post_type' => array( 'news', 'events' ),
'orderby' => 'end-date date',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'end-date',
'value' => date ( 'Ymd' ),
'type' => 'NUMERIC',
'compare' => '>='
),
array(
'key' => 'end-date',
'compare' => 'NOT EXISTS'
)
)
);
Similar to italiansoda's answer, the "OR" relationship will look for any results that satisfy either meta query with the first being specific to your events post type that use the end-date meta field, and the other will happily pull in any news post types where that meta field doesn't exist.
Furthermore, I've found that by including "meta_key" => "end-date" in the top-level array of $args also excludes the news post type. I can't tell if it's working or just coincidence that my results are ordered correctly when using "orderby" => "end-date date", essentially setting preference to order results first by the end-date meta field and then the post's publish date. But it's not breaking or excluding results with it.
Alternatively, you could do "multiple loops" to have specific control. It's not my favorite method by all means, but it works and gives you more control over the parameters for specific post types.
The first loop would be getting all of your news posts and returning them as an array of post IDs. How they're ordered or sorted doesn't matter here.
$news_ids = get_posts( array(
'fields' => 'ids',
'posts_per_page' => -1,
'post_type' => 'news',
'post_status' => 'publish',
//Add any additional parameters specific to news here
));//Returns an array of IDs
The second loop would be getting all of your events posts and returning them as an array of post IDs. How they're ordered or sorted doesn't matter here either.
$events_ids = get_posts( array(
'fields' => 'ids',
'posts_per_page' => -1,
'post_type' => 'events',
'post_status' => 'publish',
'meta_query' => array( array(
'type' => 'NUMERIC',
'key' => 'end-date',
'value' => date( 'Ymd' ),
'compare' => '>='
) ),
//Add any additional parameters specific to events here
));//Returns an array of IDs
Using those two arrays, you can merge them into a "master list" of post IDs to then use as the value for post__in in the $args array. The order of the IDs still don't matter here.
$all_ids = array_merge( $news_ids, $event_ids );//Combine all of the post IDs together into one array
$args = array(
'post_type' => array( 'news', 'events' ),//Specify both post types here still
'post__in' => $all_ids,//Only display posts from the "master list" of IDs
//Add any additional parameters for sorting all of them here like...
'orderby' => 'end-date date',
'order' => 'ASC'
);
Order and sorting will be applied in your final and third "loop" when you define them in your $args array.
relation
parameter, link to the docs?. You could run into problems with theorderby