Как передать текущие термины таксономии в новый WP_Query?

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

На своих страницах одиночного портфолио я хочу добавить раздел “Смотреть больше из этой категории” под постом.

Вот мой код, который проверяет одиночный CPT и создает новый запрос:

add_action( 'genesis_loop', 'bds_more_projects_query' );
    function bds_more_projects_query() {
        if ( is_singular( 'portfolio' ) ) {
            $categories = get_the_terms( $post->ID, 'portfolio_category' );
            $args = array(
                'post_type' => 'portfolio',
                'posts_per_page' => 4,
                'tax_query' => array(
                    array(
                        'taxonomy' => 'portfolio_category',
                        'field' => 'name',
                        'terms' => array( $categories ),
                    ),
                ),
            );
            $loop = new WP_Query( $args );
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) : $loop->the_post();
                echo the_title();
                endwhile;
            }
            wp_reset_postdata();
        }
    }

Когда я вручную ввожу строку термина, соответствующие заголовки все выводятся как нужно, но я не могу сделать так, чтобы функция “get_the_terms” работала для динамического отображения категории текущего поста.

Что мне не хватает в моем коде?

Попробуйте это:

add_action( 'genesis_loop', 'bds_more_projects_query' );
function bds_more_projects_query() {
    if ( is_singular( 'portfolio' ) ) {
        $categories = get_the_terms( $post->ID, 'portfolio_category' );
        $cat_ids = array();
        foreach ( $categories as $category ) {
            $cat_ids[] = $category->term_id;
        }
        $args = array(
            'post_type' => 'portfolio',
            'posts_per_page' => 4,
            'tax_query' => array(
                array(
                    'taxonomy' => 'portfolio_category',
                    'field' => 'id',
                    'terms' => array( $cat_ids ),
                ),
            ),
        );
        $loop = new WP_Query( $args );
        if ( $loop->have_posts() ) {
            while ( $loop->have_posts() ) : $loop->the_post();
            echo the_title();
            endwhile;
        }
        wp_reset_postdata();
    }
}

В основном, пройдите по массиву $categories, добавляя term_id каждого в новый массив, а затем используйте этот новый массив в аргументах запроса. Функция get_the_terms возвращает массив объектов WP_Term, а не просто массив ID (см. WP Code Reference для получения дополнительной информации).

Другую вещь, которую следует проверить, это то, что $post возвращает текущий пост внутри функции.

Для проверки добавьте var_dump($post) сразу внутри условия is_singular( 'portfolio' ) и убедитесь, что он возвращает объект текущего поста. Если это не так, добавьте global $post внутри функции bds_more_projects_query и попробуйте снова.

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

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

1. Суть проблемы

Ваша цель состоит в том, чтобы отобразить раздел "Смотрите больше из этой категории" на страницах отдельных записей вашего пользовательского типа записи (CPT) "portfolio". Проблема заключается в том, что функция get_the_terms возвращает массив объектов WP_Term, а не просто массив идентификаторов термов. Это означает, что для правильной работы вашего WP_Query необходимо извлечь идентификаторы терминов.

2. Исправления кода

Вот скорректированный вариант вашего кода:

add_action( 'genesis_loop', 'bds_more_projects_query' );
function bds_more_projects_query() {
    global $post; // Обеспечиваем доступ к текущему объекту поста

    if ( is_singular( 'portfolio' ) ) {
        $categories = get_the_terms( $post->ID, 'portfolio_category' );

        // Проверяем, есть ли категории
        if ($categories && !is_wp_error($categories)) {
            $cat_ids = array();

            // Извлекаем ID терминов
            foreach ( $categories as $category ) {
                $cat_ids[] = $category->term_id;
            }

            $args = array(
                'post_type' => 'portfolio',
                'posts_per_page' => 4,
                'tax_query' => array(
                    array(
                        'taxonomy' => 'portfolio_category',
                        'field' => 'term_id', // Лучше использовать ID для избавления от ошибок
                        'terms' => $cat_ids,
                    ),
                ),
            );

            // Выполняем новый запрос
            $loop = new WP_Query( $args );
            if ( $loop->have_posts() ) {
                echo '<h2>Смотрите больше из этой категории:</h2>'; // Заголовок перед списком
                echo '<ul>'; // Начинаем список
                while ( $loop->have_posts() ) : $loop->the_post();
                    echo '<li>' . get_the_title() . '</li>'; // Отображаем заголовок
                endwhile;
                echo '</ul>'; // Закрываем список
            }
            wp_reset_postdata(); // Сбрасываем данные поста
        }
    }
}

3. Основные изменения и пояснения

  1. Использование глобальной переменной $post: Для того чтобы получать текущий объект поста внутри функции, добавляется строка global $post;.

  2. Проверка на ошибки и пустые результаты: Перед тем, как обрабатывать массив категорий, нужно проверить, действительно ли он существует и не содержит ли ошибок. Для этого используется условие if ($categories && !is_wp_error($categories)).

  3. Извлечение ID терминов: Мы проходим по массиву и добавляем идентификаторы терминов в новую переменную $cat_ids.

  4. Указание поля для поиска: Используем field => 'term_id' в аргументах tax_query, что является более надежным способом.

  5. Отображение заголовка и списка: Добавлен заголовок перед выводом списка и использование маркированного списка <ul> для лучшей семантики и стилей.

4. Рекомендации по SEO

  • Использование заголовков, таких как <h2>, для разделов, помогает поисковым системам лучше индексировать и структурировать контент.
  • Добавление атрибутов rel="nofollow" к ссылкам, если это необходимо, может помочь в управлении рейтингом SEO.
  • Убедитесь, что выводимые заголовки постов являются кликабельными и ведут на страницы отдельных записей, что повышает взаимодействие с пользователем.

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

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

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