Вопрос или проблема
Мне нужно сделать сортировку постов на архивных страницах (is_archive) с помощью pre_get_posts, когда sort=trend присутствует в URL.
Я хотел бы, чтобы в начале сортировались посты с тегом (post_tag) с ID 55, а после всех постов (если они есть) в текущем запросе с этим тегом показывались другие посты без этого конкретного тега.
Таким образом, в моем случае было бы так.
- На 1-м месте последний опубликованный пост с тегом с ID 55
- На 2-м месте пост с тегом с ID 55
- На 3-м месте oldest пост с тегом с ID 55
- На 4-м месте последний опубликованный пост без тега с ID 55
- На 5-м месте пост без тега с ID 55
- На 6-м месте oldest пост без тега с ID 55
- …
Я надеюсь, вы поняли, в общем, сортировка по наличию тега с ID 55 по дате, а затем любые другие посты без этого тега также сортируются по дате.
У меня есть эта функция:
function custom_sort_posts($query) {
if (!is_admin() && $query->is_main_query() && is_archive()) { // Если это главный запрос и не в административной области, и это архив
if (isset($_GET['sort']) && $sort === 'trend') {
$trend_tag_id = pll_get_term(55); // Получить ID тега "55" на текущем языке
$tax_query[] = [
'relation' => 'OR',
[
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $trend_tag_id,
'operator' => 'IN'
],
[
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $trend_tag_id,
'operator' => 'NOT IN'
]
];
// Сортируем сначала по наличию тега, затем по дате публикации
$query->set('orderby', [
'tag__in' => 'DESC', // Посты с тегом "trend" будут на верху
'date' => 'DESC' // Сортировать по дате, самые новые на первом месте
]);
}
}
}
Это не работает, я получаю ту же сортировку постов, что и без этого.
Я надеюсь, кто-то сможет предоставить лучшую функцию, если вообще возможно сделать такую сортировку постов?
Ответ или решение
Для реализации сортировки постов на архивной странице с учётом наличия определённого тега (в вашем случае, тег с ID 55) необходимо внести правки в функцию custom_sort_posts
. Данная функция должна учитывать как наличие тега, так и дату публикации постов при сортировке.
Задача
Наша задача — отсортировать посты следующим образом:
- Все посты с тегом ID 55, отсортированные по дате — сначала самые новые.
- Все посты без тега ID 55, также отсортированные по дате — сначала самые новые.
Решение
Ниже приведённая функция учитывает эти требования. Мы будем использовать pre_get_posts
для того, чтобы изменять запрос к базе данных на этапе его формирования.
function custom_sort_posts($query) {
if (!is_admin() && $query->is_main_query() && is_archive()) { // Проверяем, что мы не в админке, это основной запрос и это архив
if (isset($_GET['sort']) && $_GET['sort'] === 'trend') { // Проверяем наличие параметра sort в URL
$trend_tag_id = 55; // ID тега, который мы ищем
// Добавляем логическое условие для запроса
$query->set('tax_query', [
'relation' => 'OR',
[
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $trend_tag_id,
'operator' => 'IN'
],
[
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $trend_tag_id,
'operator' => 'NOT IN'
],
]);
// Устанавливаем порядок сортировки
$query->set('orderby', [
'tag__in' => 'DESC', // Сортируем так, чтобы посты с тегом ID 55 были первыми
'date' => 'DESC' // Внутри групп сортируем по дате
]);
// После сортировки по тегам добавьте параметр для вывода совместно с предыдущим
$query->set('order', 'DESC');
}
}
}
add_action('pre_get_posts', 'custom_sort_posts');
Объяснение кода
-
Проверки условий:
!is_admin() && $query->is_main_query() && is_archive()
— мы удостоверяемся, что изменяем только основной запрос на архивной странице.
-
Проверка параметра:
- Проверяем, существует ли в URL параметр
sort
с значениемtrend
.
- Проверяем, существует ли в URL параметр
-
Формирование запроса:
- Запрос включен в
tax_query
, который определяет, какие посты должны быть включены в результаты поискового запроса.
- Запрос включен в
-
Сортировка:
- Используется
orderby
для сортировки сначала по наличию тега, а затем по дате публикации.
- Используется
Заключение
С помощью приведенной функции вы сможете сортировать посты в соответствии с заданными условиями. Такой подход позволяет вам находить желаемые посты и предоставляет пользователям доступ к актуальным публикациям. При тестировании убедитесь, что визуальная часть отображения также соответствует вашим ожиданиям, чтобы пользователи могли легко находить нужный контент.