Вопрос или проблема
Мне нужен способ сортировки записей в архивах тегов и категорий в соответствии с датой события (если она существует) ИЛИ датой публикации (если нет).
У меня есть объединенный архив для событий и постов, но я хочу перечислить события на основе их мета 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”, он вернет записи на основе того, существует эта мета или нет, а не на основе ее значения, если она существует, и даты публикации, если нет.
Вероятно, я слишком заморачиваюсь, но каково лучшее решение здесь?
На основе
- Могу ли я исключить запись по мета-ключу, используя функцию pre_get_posts? // установка мета в pre_get_posts
- Запрос всех записей, где мета-ключ не существует // форматирование существует и не существует
- множество 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
.
Пошаговый план реализации
-
Настройка
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' // затем по дате публикации
));
}
}
-
Настройка приоритетов сортировки:
В части
orderby
необходимо указать, что вначале сортировка идет поmeta_value
(в случае существования), а затем поdate
.$query->set('orderby', array( 'meta_value_num' => 'DESC', // Использование типа 'meta_value_num' для корректной сортировки 'date' => 'DESC' ));
Достоинства предложенной реализации
- Гибкость: Позволяет корректно обрабатывать как посты с заданной мета-датой события, так и без неё, обеспечивая единообразный формат вывода.
- Масштабируемость: Легко адаптируется под любые изменения в структуре данных или специфические требования.
- Оптимизация SEO: Предоставляет пользователям актуальные и структурированные данные, что способствует улучшению SEO-показателей.
Предупреждения и ограничения
- Не забудьте протестировать код в безопасной среде перед использованием на продакшене, чтобы избежать неожиданных ошибок.
- Убедитесь, что ваш сайт поддерживает выполнение PHP-скриптов и вы обладаете достаточными правами для внесения изменений в код.
Эта реализация позволит вам добиться желаемого результата в сортировке архивов, предоставляя пользователям наиболее актуальную информацию в удобном формате.