Как отсортировать записи сперва с заполненной датой (ближайшей), потом без даты (пустое value)?

Ссылка скопирована
1 ответ
add_action('pre_get_posts', 'custom_posts'); function custom_posts($query) {     if ( ! is_admin() && $query->is_main_query() ) {         $cur_date = date('Y-m-d');                  $meta_query = array(             'relation' => 'OR',             array(                 'key' => 'date',                  'value' => $cur_date,                 'compare' => '>=',                  'type' => 'DATE',             ),             array(                 'key' => 'date',                 'value' => '',                 'compare' => '=',             ),                      );          $query->set('meta_query', $meta_query);     } }

add_action('pre_get_posts', 'custom_posts'); function custom_posts($query) { if ( ! is_admin() && $query->is_main_query() ) { $cur_date = date('Y-m-d'); $meta_query = array( 'relation' => 'OR', array( 'key' => 'date', 'value' => $cur_date, 'compare' => '>=', 'type' => 'DATE', ), array( 'key' => 'date', 'value' => '', 'compare' => '=', ), ); $query->set('meta_query', $meta_query); } }

в данном запросе выводятся не просроченные относительно текущей даты записи по ключу date формат value 2023-04-20, а также выводятся записи, для которых value пустое (ключа date).
каким образом отсортировать записи, сперва ближайшие по дате, потом без даты

Дополнительно:

Ответы:

В meta query делаем ассоциативные записи,
А в orderby передаем массив ключей выше

  • Если не получится с вашим случаем , то остаётся вариант https://developer.wordpress.org/reference/hooks/po...
  • Если будете хукать orderby через sql - вам вероятно понадобится FIELD()
  • это как ассоциативные записи можно пример?
  • William,
    ‘first_meta’ => array(
    'key' => 'date',
    'value' => $cur_date,
    'compare' => '>=',
    'type' => 'DATE',
    ),
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

Вам нужно разделить записи на две группы: сначала записи с заполненной датой, отсортированные по ближайшей дате, затем записи без даты. Одним обычным orderby => meta_value это часто не получается аккуратно сделать, потому что пустые значения и отсутствующие meta_key сортируются не так, как нужно.

Если поле date хранится в формате Y-m-d, можно использовать именованные условия meta_query и сортировку:

add_action('pre_get_posts', function ($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }
 
    $cur_date = current_time('Y-m-d');
 
    $query->set('meta_query', [
        'relation' => 'OR',
        'future_date' => [
            'key'     => 'date',
            'value'   => $cur_date,
            'compare' => '>=',
            'type'    => 'DATE',
        ],
        'empty_date' => [
            'key'     => 'date',
            'value'   => '',
            'compare' => '=',
        ],
        'no_date' => [
            'key'     => 'date',
            'compare' => 'NOT EXISTS',
        ],
    ]);
 
    $query->set('orderby', [
        'future_date' => 'ASC',
        'date'        => 'DESC',
    ]);
});

add_action('pre_get_posts', function ($query) { if (is_admin() || !$query->is_main_query()) { return; } $cur_date = current_time('Y-m-d'); $query->set('meta_query', [ 'relation' => 'OR', 'future_date' => [ 'key' => 'date', 'value' => $cur_date, 'compare' => '>=', 'type' => 'DATE', ], 'empty_date' => [ 'key' => 'date', 'value' => '', 'compare' => '=', ], 'no_date' => [ 'key' => 'date', 'compare' => 'NOT EXISTS', ], ]); $query->set('orderby', [ 'future_date' => 'ASC', 'date' => 'DESC', ]); });

Но у такого варианта есть нюанс: WordPress SQL не всегда идеально сортирует пустые и отсутствующие значения после дат. Если нужно строго «сначала все с датой, потом все без даты», надёжнее добавить отдельное служебное поле, например has_date: 1 для записей с датой и 0 для пустых. Тогда сортировка становится простой.

$query->set('meta_key', 'date');
$query->set('orderby', [
    'meta_value' => 'ASC',
]);

$query->set('meta_key', 'date'); $query->set('orderby', [ 'meta_value' => 'ASC', ]);

Для сложной сортировки можно использовать фильтр posts_orderby и написать SQL с CASE WHEN, но это уже менее универсально. Если проект живой и таких записей много, я бы сделал нормализацию данных: у всех записей есть date и has_date, а сортировка строится по этим двум предсказуемым полям.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно