Вопрос или проблема
Я хотел бы создать 3-уровневый иерархический список терминов в рамках пользовательской таксономии, который включает до 10 постов только в термин(ы) нижнего уровня.
например:
Пользовательская таксономия
- Родительский термин 1
-- Дочерний термин 1
--- Пост 1
--- Пост 2
-- Дочерний термин 2
--- Пост 1
--- Пост 2
--- Пост 3
--- Пост 4
-- Дочерний термин 3
и т.д.
Я хотел бы в конечном итоге отобразить их в наборе “спойлеров” или в формате “аккордеона”, но уверен, что могу разобраться с этой частью самостоятельно.
Я рассматривал несколько вариантов, таких как wp_list_categories() и одну-две пользовательские функции, но пока еще не смог найти решение. Любая помощь в этом будет очень признательна.
Сегодня днем я работал над решением и придумал следующее. Возможно, это не самый изящный способ сделать это, поэтому я открыт для дальнейших комментариев.
function custom_tax_list_and_posts() {
$post_type="CUSTOM_POST_TYPE_NAME";
$taxonomy = 'CUSTOM_TAXONOMY_NAME';
// Получить все родительские термины в пользовательской таксономии и включить пустые
$parent_terms = get_terms( $taxonomy, array( 'parent' => 0, 'hide_empty' => false ) );
echo '<ul>';
// Начать перебор родительских терминов
foreach( $parent_terms as $pterm ) :
// Получить все дочерние термины только в рамках родительского термина
$child_terms = get_terms( $taxonomy, array( 'parent' => $pterm->term_id, 'hide_empty' => false ) );
echo '<li>';
echo '<h3>' . $pterm->name . '</h3>';
echo '<ul>';
// Начать перебор дочерних терминов
foreach( $child_terms as $cterm ) :
echo '<li>';
echo '<h3>' . $cterm->name . '</h3>';
// Настроить аргументы для пользовательских постов
$args = array(
'post_type' => $post_type,
'posts_per_page' => 10, // Или сколько вам нужно
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $cterm->slug
)
)
);
query_posts($args);
if ( have_posts() ) :
echo '<ul>';
// Начать перебор постов только в дочерних терминах
while ( have_posts() ) : the_post();
echo '<li>';
echo '<p class="post-date">' . get_the_date('j F Y') . '</p>';
echo '<h3><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></h3>';
echo '<p>' . get_the_excerpt() . '</p>';
echo '<a class="read-more" href="'. get_the_permalink() . '">Читать далее ...</a>';
echo '</li>';
endwhile;
echo '</ul>';
endif;
endforeach;
echo '</ul>';
echo '</li>';
endforeach;
echo '</ul>';
}
Ответ или решение
Создание иерархического списка пользовательских таксономий и постов в WordPress — это задача, которая требует внимательного планирования и реализации. Рассмотрим детальный подход к решению этой проблемы.
Описание задачи
Требуется создать трёхуровневый иерархический список, который будет включать термины пользовательской таксономии с выводом до 10 постов для каждого термина нижнего уровня. Изначально планируется использовать HTML для структуры списков, а позже — реализовать отображение в формате "спойлеров" или "аккордеона". Рассмотрим, как это можно реализовать с помощью PHP в WordPress.
Решение
Следующий кодовый пример демонстрирует, как создать структуру, подобную обозначенной в задаче.
function custom_tax_list_and_posts() {
$post_type = "CUSTOM_POST_TYPE_NAME"; // Укажите название вашего типа постов
$taxonomy = 'CUSTOM_TAXONOMY_NAME'; // Укажите название вашей пользовательской таксономии
// Получение всех родительских терминов указанной таксономии, включая пустые
$parent_terms = get_terms($taxonomy, array('parent' => 0, 'hide_empty' => false));
echo '<ul>';
// Перебор родительских терминов
foreach ($parent_terms as $pterm) {
// Получение дочерних терминов для каждого родительского термина
$child_terms = get_terms($taxonomy, array('parent' => $pterm->term_id, 'hide_empty' => false));
echo '<li>';
echo '<h3>' . $pterm->name . '</h3>';
echo '<ul>';
// Перебор дочерних терминов
foreach ($child_terms as $cterm) {
echo '<li>';
echo '<h3>' . $cterm->name . '</h3>';
// Настройка параметров запроса для получения постов
$args = array(
'post_type' => $post_type,
'posts_per_page' => 10, // Ограничение на количество постов
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $cterm->slug
)
)
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
// Перебор постов для каждого дочернего термина
while ($query->have_posts()) : $query->the_post();
echo '<li>';
echo '<p class="post-date">' . get_the_date('j F Y') . '</p>';
echo '<h3><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></h3>';
echo '<p>' . get_the_excerpt() . '</p>';
echo '<a class="read-more" href="' . get_the_permalink() . '">Читать дальше ...</a>';
echo '</li>';
endwhile;
echo '</ul>';
wp_reset_postdata();
}
echo '</li>';
}
echo '</ul>';
echo '</li>';
}
echo '</ul>';
}
Объяснение кода
-
Выбор таксономии и типа поста: В начале функции указаны имена пользовательской таксономии и пользовательского типа поста, которые будут использоваться для генерации списка.
-
Получение родительских терминов: Используя
get_terms()
, мы получаем все родительские термины, чтобы затем получить для каждого его дочерние элементы. -
Вывод терминов и постов: Для каждого дочернего термина выполняется WP_Query, который выбирает посты, принадлежащие данному термину. Результаты выводятся в виде вложенного списка HTML.
-
Управление данными запроса: Не забываем сбросить глобальную переменную поста с помощью
wp_reset_postdata()
, чтобы избежать конфликтов с другими запросами.
Этот код создает сложную, иерархическую структуру навигации по таксономиям и записям, обеспечивая быстрый доступ к данным, структурированным в рамках WordPress. Стоит также отметить потенциал для улучшения кода путём интеграции форматов отображения, таких как "спойлеры" или "аккордеоны", с использованием CSS или JavaScript.