По дате - нет проблем. Все, что нужно - сделать strtotime кастомного поля. Например:
$params = array(
'post_type' => 'events', //кастомный тип постов, меняй на любой
);
$posts = get_posts($params); //получаем массив постов
$events_date = wp_list_pluck( $posts, 'event_date'); //получаем массив из кастомного поля с датой
$res = array_unique($events_date); //Удаляем дубликаты
function date_sort($a, $b) {
return strtotime($a) - strtotime($b);
}
usort($res, "date_sort"); // сортируем по возрастанию дат
Далее все просто, запускаем цикл
if( $res ){
foreach( $res as $result ){
$args = array( //задаем аргументы wp_query
'post_type' => 'events', //тип поста
'showposts' => 3, //сколько постов
'meta_key' => 'event_time', //по какому полю сортируем
'orderby' => 'meta_value_num',
'order' => 'ASC', //возрастание или убывание
);
query_posts($args);
if ( have_posts() )
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content-events', get_post_format() ); //относительная ссылка на твой шаблон
endwhile;
}
};
На этом все
Что касается удаления просроченных постов - их не обязательно удалять, можно просто не включать в цикл, например:
//Цикл
if ( have_posts() )
//Для функции date() обязательно используем date_default_timezone_set("Временная зона"), в противном случае получим дату по GMT +0, а нам нужно к примеру по МСК
date_default_timezone_set("Europe/Moscow");//Используем зону МСК для примера, с списком доступных таймзон можно ознакомится в гугле, например
$forBefore = strftime("%d.%m.%Y", strtotime($result)); //получаем дату поста
$forToday = date("d.m.Y"); //сегодняшняя дата
if (strtotime($forToday) >= strtotime($forBefore)){ //Если дата равна или больше сегодняшней
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content-events', get_post_format() ); //относительная ссылка на твой шаблон
endwhile;
}
};
Соответственно, если дата поста просрочена - пост просто не будет выводится, это может пригодится, чтобы например просто перенести дату предыдущей экскурсии и не заполнять заново