Сортировка постов по наличию определенного тега поста

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

Мне нужно сделать сортировку постов на архивных страницах (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. Данная функция должна учитывать как наличие тега, так и дату публикации постов при сортировке.

Задача

Наша задача — отсортировать посты следующим образом:

  1. Все посты с тегом ID 55, отсортированные по дате — сначала самые новые.
  2. Все посты без тега 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');

Объяснение кода

  1. Проверки условий:

    • !is_admin() && $query->is_main_query() && is_archive() — мы удостоверяемся, что изменяем только основной запрос на архивной странице.
  2. Проверка параметра:

    • Проверяем, существует ли в URL параметр sort с значением trend.
  3. Формирование запроса:

    • Запрос включен в tax_query, который определяет, какие посты должны быть включены в результаты поискового запроса.
  4. Сортировка:

    • Используется orderby для сортировки сначала по наличию тега, а затем по дате публикации.

Заключение

С помощью приведенной функции вы сможете сортировать посты в соответствии с заданными условиями. Такой подход позволяет вам находить желаемые посты и предоставляет пользователям доступ к актуальным публикациям. При тестировании убедитесь, что визуальная часть отображения также соответствует вашим ожиданиям, чтобы пользователи могли легко находить нужный контент.

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

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