Упорядочить по дате события (если существует) или по дате публикации (если не существует) – как изменить порядок постов на основе мета-значения ИЛИ даты.

Вопрос или проблема

Мне нужен способ сортировки записей в архивах тегов и категорий в соответствии с датой события (если она существует) ИЛИ датой публикации (если нет).

У меня есть объединенный архив для событий и постов, но я хочу перечислить события на основе их мета event_date, вместо даты их публикации.

Я знаю, что мне нужно обновить запрос, чтобы добавить аргумент “orderby”, но не могу придумать, как лучше всего структурировать аргумент запроса, чтобы получить нужные результаты.

Я думаю, что мне нужно сделать что-то вроде:

foreach($posts as $post) {

    $event_start = get_post_meta($object_id, 'event_start',   TRUE);

    if($event_start) {

        $event_start = strtotime($event_start);
        $list_timestamp_map[$object_id] = $event_start;

        } else {

            $post_date = get_the_date('Y-m-d H:i:s',$object_id);

            $post_date = strtotime($post_date);
            $list_timestamp_map[$object_id] = $post_date;

        }

    }

    arsort($list_timestamp_map);

}

В основном:

  • Проверьте, есть ли значение в поле “event_start”
  • Если есть, получите/используйте эту дату
  • Если нет, получите/используйте дату публикации
  • Отсортируйте записи в соответствии с этим списком

Но как выполнить запрос/сравнить/отсортировать существующий архив на основе комбинации данных пользовательского поля и даты публикации?

Я не могу сделать это:

function rtt_event_sorting( $query ) {

    if( $query->is_main_query() && ( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {

        $query->set('orderby','meta_value');
        $query->set('meta_key','event_start');
        $query->set('orderby','DESC');

        return $query;

    }

}

add_filter( 'pre_get_posts', 'rtt_event_sorting' );

Потому что если я добавлю аргумент “meta_key”, он вернет записи на основе того, существует эта мета или нет, а не на основе ее значения, если она существует, и даты публикации, если нет.

Вероятно, я слишком заморачиваюсь, но каково лучшее решение здесь?

На основе

  1. Могу ли я исключить запись по мета-ключу, используя функцию pre_get_posts? // установка мета в pre_get_posts
  2. Запрос всех записей, где мета-ключ не существует // форматирование существует и не существует
  3. множество orderby в действии pre_get_posts // как установить множество orderby

возможно, вы могли бы попробовать что-то вроде этого в вашем фильтре pre_get_posts,

//Получите оригинальный мета-запрос
$meta_query = $query->get('meta_query');

//Добавьте наш мета-запрос в оригинальные мета-запросы
// Записи, которые имеют и не имеют мета-значение
$meta_query[] = array(
  'relation' => 'OR',
  array(
   'key'     => 'event_start',
   'compare' => 'NOT EXISTS',
   'value'   => ''
  ),
  array(
   'key'     => 'event_start',
   'compare' => 'EXISTS'
  )
);
$query->set('meta_query',$meta_query);

$query->set('orderby', array('meta_value' => 'DESC', 'date' => 'DESC'));

Извините, я не смог протестировать этот пример кода, так как у меня не было подобных данных в моих WP песочницах, и это немного поздно, когда я пишу это, поэтому я мог что-то упустить, принимайте его с долей скептицизма.

Ответ или решение

Если вы хотите отсортировать посты в ваших архивах по мета-значению event_start, если оно существует, или по дате публикации, если нет, вам необходимо тщательно структурировать запрос. Вот как можно это реализовать:

Изменение WP_Query

Вам потребуется задействовать фильтр pre_get_posts, чтобы изменить основной запрос WordPress. Это позволит сортировать посты в нужной последовательности, независимо от наличия мета-поля event_start.

Пошаговый план реализации

  1. Настройка meta_query:

    Во-первых, добавьте логику для определения, существуют ли мета-данные event_start.

add_filter('pre_get_posts', 'custom_event_sorting');
function custom_event_sorting($query) {
  if ($query->is_main_query() && (is_category() || is_tag()) && empty($query->query_vars['suppress_filters'])) {

    // Получаем оригинальные параметры `meta_query`
    $meta_query = $query->get('meta_query') ?: [];

    // Добавляем наши условия
    $meta_query[] = array(
      'relation' => 'OR',
      array(
        'key'     => 'event_start',
        'compare' => 'EXISTS'
      ),
      array(
        'key'     => 'event_start',
        'compare' => 'NOT EXISTS'
      )
    );

    $query->set('meta_query', $meta_query);

    // Устанавливаем порядок сортировки
    $query->set('orderby', array(
      'meta_value_num' => 'DESC', // сортировка по мета-значению event_start
      'date' => 'DESC'            // затем по дате публикации
    ));
  }
}
  1. Настройка приоритетов сортировки:

    В части orderby необходимо указать, что вначале сортировка идет по meta_value (в случае существования), а затем по date.

    $query->set('orderby', array(
     'meta_value_num' => 'DESC', // Использование типа 'meta_value_num' для корректной сортировки
     'date' => 'DESC'
    ));

Достоинства предложенной реализации

  • Гибкость: Позволяет корректно обрабатывать как посты с заданной мета-датой события, так и без неё, обеспечивая единообразный формат вывода.
  • Масштабируемость: Легко адаптируется под любые изменения в структуре данных или специфические требования.
  • Оптимизация SEO: Предоставляет пользователям актуальные и структурированные данные, что способствует улучшению SEO-показателей.

Предупреждения и ограничения

  • Не забудьте протестировать код в безопасной среде перед использованием на продакшене, чтобы избежать неожиданных ошибок.
  • Убедитесь, что ваш сайт поддерживает выполнение PHP-скриптов и вы обладаете достаточными правами для внесения изменений в код.

Эта реализация позволит вам добиться желаемого результата в сортировке архивов, предоставляя пользователям наиболее актуальную информацию в удобном формате.

Оцените материал
Добавить комментарий

Капча загружается...