При разработке сложных сайтов на WordPress часто возникает необходимость реализовать иерархическую структуру не только для страниц, но и для кастомных типов записей (Custom Post Types, CPT). Однако стандартная иерархия WordPress поддерживается только для страниц и некоторых типов постов. В этой статье мы разберём, как создать виртуальные иерархии для любых типов постов, чтобы улучшить навигацию, фильтрацию и организацию контента.
Что такое виртуальная иерархия и зачем она нужна в WordPress
Виртуальная иерархия — это структура, которая создаётся программно и не привязана напрямую к родительским и дочерним записям WordPress. Она позволяет группировать записи в логические цепочки или уровни, имитируя древовидную структуру, даже если родительские связи не используются. Это особенно полезно для типов постов, которые не поддерживают иерархию по умолчанию, например, проекты, товары, события и т.д.
Такая иерархия помогает:
- Упорядочить контент по дополнительным атрибутам;
- Создавать сложные меню и навигационные цепочки;
- Обеспечивать удобный UX для пользователей;
- Улучшать SEO за счёт логичной структуры URL и внутренней перелинковки.
Как задать виртуальную иерархию через кастомные поля
Используем кастомные поля для создания связей между CPT
Один из самых простых способов — добавить кастомное поле, которое будет хранить ID родительской записи. Для этого можно использовать Advanced Custom Fields (ACF) или вручную зарегистрировать метаполе.
Пример регистрации метаполя с помощью функции add_post_meta:
function wphierarchy_add_parent_meta($post_id, $parent_id) {
update_post_meta($post_id, '_wphierarchy_parent_id', $parent_id);
}
Далее при выводе записей нужно учитывать это поле, чтобы построить иерархию.
Пример функции для получения дочерних элементов
function wphierarchy_get_children($parent_id, $post_type = 'project') {
$args = [
'post_type' => $post_type,
'meta_key' => '_wphierarchy_parent_id',
'meta_value' => $parent_id,
'posts_per_page' => -1
];
return get_posts($args);
}
Эта функция позволяет получить все дочерние записи определённого типа для заданного родителя.
Строим рекурсивный вывод виртуальной иерархии
Чтобы вывести всю структуру, можно реализовать рекурсивную функцию, которая будет обходить все уровни и формировать дерево.
function wphierarchy_render_tree($parent_id = 0, $post_type = 'project') {
$children = wphierarchy_get_children($parent_id, $post_type);
if (empty($children)) {
return;
}
echo '<ul>';
foreach ($children as $child) {
echo '<li>' . esc_html($child->post_title);
wphierarchy_render_tree($child->ID, $post_type);
echo '</li>';
}
echo '</ul>';
}
Вызов wphierarchy_render_tree(0, 'project') выведет все корневые проекты и их вложенные элементы.
Использование плагина для создания виртуальной иерархии
Если хочется упростить задачу, можно использовать готовые решения. Например, плагин Hierarchical Posts расширяет возможности иерархии на произвольные типы записей.
Ещё один вариант — плагин Clearfy Pro, который среди прочих функций позволяет настроить расширенную структуру иерархии и оптимизировать вывод.
Настройка ЧПУ для виртуальной иерархии
Очень важно, чтобы URL отражали структуру иерархии, даже если она виртуальная. Для этого можно использовать фильтр post_type_link и перезаписывать правила пермалинков.
Пример фильтра для формирования ЧПУ
function wphierarchy_custom_post_type_link($post_link, $post) {
if ($post->post_type !== 'project') {
return $post_link;
}
$parent_id = get_post_meta($post->ID, '_wphierarchy_parent_id', true);
if ($parent_id) {
$parent = get_post($parent_id);
if ($parent) {
$parent_slug = $parent->post_name;
$post_link = home_url("/project/{$parent_slug}/" . $post->post_name . "/");
}
}
return $post_link;
}
add_filter('post_type_link', 'wphierarchy_custom_post_type_link', 10, 2);
Не забудьте добавить правила перезаписи через add_rewrite_rule, чтобы WordPress мог распознавать такие URL.
Обработка AJAX-запросов для динамической загрузки иерархии
Если иерархия большая, удобно подгружать уровни по мере необходимости с помощью AJAX. В этом случае создайте обработчик на PHP, который будет возвращать дочерние записи в JSON формате, а на фронтенде — скрипт для динамического раскрытия разделов.
Пример обработчика AJAX в WordPress
add_action('wp_ajax_wphierarchy_load_children', 'wphierarchy_load_children_callback');
add_action('wp_ajax_nopriv_wphierarchy_load_children', 'wphierarchy_load_children_callback');
function wphierarchy_load_children_callback() {
$parent_id = intval($_POST['parent_id']);
$children = wphierarchy_get_children($parent_id, 'project');
$result = [];
foreach ($children as $child) {
$result[] = [
'id' => $child->ID,
'title' => $child->post_title,
'permalink' => get_permalink($child->ID)
];
}
wp_send_json_success($result);
wp_die();
}
Краткий пример JavaScript для загрузки дочерних элементов
jQuery(document).on('click', '.load-children-btn', function() {
var parentId = jQuery(this).data('parent-id');
jQuery.post(ajaxurl, {
action: 'wphierarchy_load_children',
parent_id: parentId
}, function(response) {
if(response.success) {
// обработать и вставить дочерние записи в DOM
}
});
});
Советы по оптимизации и безопасности
При работе с виртуальными иерархиями важно:
- Кэшировать результаты запросов, чтобы снизить нагрузку на базу данных;
- Валидация и проверка прав пользователя при обработке AJAX-запросов;
- Использовать nonce для защиты запросов от CSRF;
- Оптимизировать запросы, добавляя индексы по метаполям в базе данных при необходимости;
- Тестировать производительность на больших объёмах данных.
Применяя эти рекомендации, вы сможете создавать гибкие, расширяемые и удобные для пользователей иерархические структуры в WordPress, выходящие за рамки классической модели страниц.
Для расширения функционала и упрощения работы с иерархиями рекомендуем ознакомиться с плагинами Clearfy Pro и WPCommunity, которые поддерживают расширенную иерархию и удобный интерфейс для управления кастомными типами записей.