Here’s a suggestion using posts_orderby
filter and CASE
, UNIX_TIMESTAMP
and DATEDIFF
(that outputs number of days) from MySQL for conditional SQL ordering:
add_filter( 'posts_orderby', function( $orderby, $q ) use (&$wpdb) {
if( ! $q->is_main_query() ) {
return $orderby;
}
return $wpdb->prepare(
'CASE
WHEN DATEDIFF( %i.post_date, NOW() ) <= 14
THEN -UNIX_TIMESTAMP( %i.post_date )
ELSE %i.post_title
END ASC',
"{$wpdb->posts}",
"{$wpdb->posts}",
"{$wpdb->posts}"
);
}, 10, 2 );
This might probably be simplified with e.g. numbered arguments like %1$i
if that’s supported by the new prepare-placeholder %i
for table/field names.
To avoid using two order-by fields with two cases, to handle both ASC and DESC ordering, I instead suggest using a single order-by field with a single ASC order by using negative unix timestamps for the date ordering.
Hope you can test this further.