Вопрос или проблема
На своих страницах одиночного портфолио я хочу добавить раздел “Смотреть больше из этой категории” под постом.
Вот мой код, который проверяет одиночный 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. Основные изменения и пояснения
-
Использование глобальной переменной
$post
: Для того чтобы получать текущий объект поста внутри функции, добавляется строкаglobal $post;
. -
Проверка на ошибки и пустые результаты: Перед тем, как обрабатывать массив категорий, нужно проверить, действительно ли он существует и не содержит ли ошибок. Для этого используется условие
if ($categories && !is_wp_error($categories))
. -
Извлечение ID терминов: Мы проходим по массиву и добавляем идентификаторы терминов в новую переменную
$cat_ids
. -
Указание поля для поиска: Используем
field => 'term_id'
в аргументахtax_query
, что является более надежным способом. -
Отображение заголовка и списка: Добавлен заголовок перед выводом списка и использование маркированного списка
<ul>
для лучшей семантики и стилей.
4. Рекомендации по SEO
- Использование заголовков, таких как
<h2>
, для разделов, помогает поисковым системам лучше индексировать и структурировать контент. - Добавление атрибутов
rel="nofollow"
к ссылкам, если это необходимо, может помочь в управлении рейтингом SEO. - Убедитесь, что выводимые заголовки постов являются кликабельными и ведут на страницы отдельных записей, что повышает взаимодействие с пользователем.
С учетом этих рекомендаций, ваш код не только станет более нормализованным, но и обеспечит высокое качество пользовательского опыта.