Показать только топ-3 поста из 3 категорий в порядке на главной странице

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

Эта функция покажет последние 3 сообщения из любой категории на главной странице:

  // Только топ-3 сообщения из категории CHR
  add_action('pre_get_posts', 'ad_filter_categories');
  function ad_filter_categories($query) {
  if ($query->is_main_query() && is_home()) {
  $query->set('category_name','chatham-house-rules');
  $query->set('showposts', 3);
}

Я хочу сделать это еще дважды с двумя другими категориями, но это будет работать только с одной. Кроме того, это по умолчанию зависит от настройки posts_per_page в панели администратора. Есть идеи, как я могу добиться 3 последних сообщений из 3 категорий в определенном порядке на главной странице?

Существует несколько способов решения этой задачи, но один из вариантов, который я бы рассмотрел на вашем месте, был бы таким. На index.php или другой странице, где отображаются сообщения, выполните следующее трижды, каждый раз с разными категориями:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$arguments = array(
    'category_name' => 'category',
    'posts_per_page' => 3,
    'paged' => $paged
);
$wp_query->query($arguments);
if (have_posts()) :
   while (have_posts()) : the_post();
       the_content();
    endwhile;
endif;

category_name может быть строкой, разделенной запятыми, что должно позволить вам иметь три или более категории.

Параметр paged необходим при установке числа сообщений на странице таким образом. Если это не сделать, то сообщения не будут правильно отображаться на следующих страницах с записями.

Справка WP_Query показывает все фильтры, которые могут быть использованы в запросе. Она также предлагает альтернативный способ использования запроса.

WP_Query позволяет вам определить множество сложных критериев выбора для соответствия индивидуальным сообщениям. Однако то, что вам нужно, по сути, является критерием для полного набора, который возвращается из запроса. Это оставляет вам два возможных подхода:

  1. Используйте один запрос, который возвращает достаточное количество сообщений, чтобы вы были уверены, что по крайней мере одно сообщение из каждой категории присутствует. Затем переберите этот набор и выберите первое сообщение из каждой категории.
  2. Используйте три запроса, которые вернут по одному сообщению из каждой категории и объедините результаты.

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

Определите массив $categories, где каждый ключ — это слаг категории, а соответствующее значение — это порядок, в котором вы хотите отображать категории на главной странице.

Замените category-2-slug и category-3-slug на фактические слаги ваших категорий.

add_action('pre_get_posts', 'ad_filter_categories');

function ad_filter_categories($query) {
    // Проверьте, является ли это основным запросом и это главная страница
    if ($query->is_main_query() && is_home()) {
        // Настройте массив слагов категорий и соответствующим им порядком
        $categories = array(
            'chatham-house-rules' => 1, // Категория 1
            'category-2-slug' => 2, // Категория 2
            'category-3-slug' => 3, // Категория 3
        );

        // Отсортируйте категории по их порядку
        asort($categories);

        // Инициализируйте пустой массив для хранения запросов по категориям
        $category_queries = array();

        // Переберите отсортированные категории
        foreach ($categories as $category_slug => $order) {
            // Настройте параметры запроса для каждой категории
            $category_query_args = array(
                'category_name' => $category_slug,
                'posts_per_page' => 3, // Ограничьте 3 сообщениями на категорию
            );

            // Добавьте параметры запроса в массив
            $category_queries[] = $category_query_args;
        }

        // Объедините отдельные запросы по категориям, используя 'relation' => 'OR' для их объединения
        $query->set('post_type', 'post');
        $query->set('posts_per_page', -1); // Установите высокое значение, чтобы обеспечить получение всех сообщений
        $query->set('meta_key', 'date');
        $query->set('orderby', 'meta_value');
        $query->set('order', 'DESC');
        $query->set('meta_query', array(array('key' => '_thumbnail_id')));
        $query->set('tax_query', array(
            'relation' => 'OR',
            $category_queries
        ));
    }
}

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

Чтобы отобразить на главной странице вашего сайта WordPress по три последних поста из трех различных категорий в определенном порядке, можно воспользоваться функциональностью WordPress и его классом WP_Query. Данная задача предполагает необходимость создания одного запроса, который будет извлекать и отображать нужные посты, множественные запросы могут ухудшить производительность сайта.

1. Подготовка коду

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

2. Реализация кода в functions.php

Добавьте следующий код в файл functions.php вашей темы:

add_action('pre_get_posts', 'filter_categories');

function filter_categories($query) {
    // Проверяем, что это основной запрос и главная страница
    if ($query->is_main_query() && is_home()) {
        // Задаем параметры запроса
        $query->set('posts_per_page', -1); // Забираем все посты
        $query->set('post_type', 'post');
    }
}

// Выводим посты на главной странице
function display_latest_posts_from_categories() {
    // Определяем категории
    $categories = array(
        'chatham-house-rules' => 1,
        'category-2-slug' => 2,
        'category-3-slug' => 3,
    );

    // Сортируем категории по порядку
    asort($categories);

    // Массив для хранения постов
    $posts_output = array();

    foreach ($categories as $category_slug => $order) {
        $args = array(
            'category_name' => $category_slug,
            'posts_per_page' => 3,
            'order' => 'DESC',
            'orderby' => 'date',
        );

        $category_posts = new WP_Query($args);

        if ($category_posts->have_posts()) {
            $posts_output[$category_slug] = $category_posts->posts;
        }
    }

    // Вывод постов
    foreach ($posts_output as $category_slug => $posts) {
        echo '<h2>' . ucfirst(str_replace('-', ' ', $category_slug)) . '</h2>'; // Заголовок категории
        echo '<ul>';

        foreach ($posts as $post) {
            setup_postdata($post);
            echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
        }

        wp_reset_postdata(); // Сбрасываем данные
        echo '</ul>';
    }
}

// Хук для вывода на главной странице
add_action('the_content', 'display_latest_posts_from_categories');

3. Описание кода

  • Функция filter_categories(): Настраивает основной запрос, позволяя получать все посты для последующей фильтрации по категориям. Мы устанавливаем posts_per_page на -1, чтобы извлечь все посты для предварительной обработки.

  • Функция display_latest_posts_from_categories():

    • Определяет массив категорий, каждая из которых будет выведена на главной странице.
    • Создает цикл foreach, который производит запрос через WP_Query для каждой категории, ограничивая результаты тремя последними постами.
    • В конце выводит заголовок категории и список постов в формате HTML, используя ссылки на полные версии постов.

4. Заключение

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

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

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