При разработке сложных интерфейсов на WordPress часто возникает задача построить многоуровневую иерархию виджетов, где вложенные виджеты динамически загружаются по мере необходимости. Такой подход улучшает производительность за счет уменьшения первоначальной загрузки, а также повышает удобство пользователя. В этой статье мы разберем, как реализовать подобную иерархию виджетов с помощью AJAX и собственных хуков WordPress.
Почему нужна динамическая подгрузка виджетов
Стандартные виджеты WordPress выводятся статично при загрузке страницы. Если виджетов много и они составляют сложную иерархию, то страница может загружаться долго и перегружать сервер. Кроме того, не всегда пользователю нужны все уровни вложенности сразу.
Динамическая подгрузка позволяет загружать только верхний уровень виджетов, а вложенные подгружать по запросу — например, при клике на виджет-родитель. Это экономит ресурсы и улучшает UX.
Для реализации пригодится AJAX, чтобы без перезагрузки страницы получать нужные данные с сервера.
Основная логика построения иерархии виджетов
Иерархия виджетов строится на связях «родитель — дочерний виджет». Для этого у каждого виджета должен быть идентификатор родителя (parent_id). На сервере мы можем получить список виджетов с parent_id = 0 (верхний уровень), а вложенные — по parent_id равному id родителя.
Для хранения иерархии можно использовать пользовательское поле или опцию, а для простоты примера — массив в коде.
Пример структуры виджетов
$wphierarchy_widgets = [
['id' => 1, 'title' => 'Виджет 1', 'parent_id' => 0],
['id' => 2, 'title' => 'Виджет 2', 'parent_id' => 0],
['id' => 3, 'title' => 'Вложенный Виджет 1.1', 'parent_id' => 1],
['id' => 4, 'title' => 'Вложенный Виджет 1.2', 'parent_id' => 1],
['id' => 5, 'title' => 'Вложенный Виджет 3.1', 'parent_id' => 3],
];
Создание AJAX обработчика в WordPress
Для динамической подгрузки создадим AJAX-обработчик, который по ID родителя будет отдавать вложенные виджеты.
Добавим следующий код в functions.php вашей темы или в кастомный плагин:
function wphierarchy_get_child_widgets() {
// Проверка nonce для безопасности
check_ajax_referer('wphierarchy_nonce', 'nonce');
$parent_id = isset($_POST['parent_id']) ? intval($_POST['parent_id']) : 0;
// Здесь по идее получаем виджеты из базы, упростим на массиве
$widgets = [
['id' => 1, 'title' => 'Виджет 1', 'parent_id' => 0],
['id' => 2, 'title' => 'Виджет 2', 'parent_id' => 0],
['id' => 3, 'title' => 'Вложенный Виджет 1.1', 'parent_id' => 1],
['id' => 4, 'title' => 'Вложенный Виджет 1.2', 'parent_id' => 1],
['id' => 5, 'title' => 'Вложенный Виджет 3.1', 'parent_id' => 3],
];
$child_widgets = array_filter($widgets, function($w) use ($parent_id) {
return $w['parent_id'] === $parent_id;
});
wp_send_json(array_values($child_widgets));
}
add_action('wp_ajax_wphierarchy_get_child_widgets', 'wphierarchy_get_child_widgets');
add_action('wp_ajax_nopriv_wphierarchy_get_child_widgets', 'wphierarchy_get_child_widgets');
Этот обработчик получает ID родителя и возвращает JSON с дочерними виджетами.
Вывод и инициализация иерархии на фронтенде
Выведем верхний уровень виджетов и добавим возможность подгружать вложенные по клику. Для работы AJAX используем jQuery.
В шаблоне или блоке вставляем HTML и JS:
<div id="wphierarchy-widgets">
<ul class="wphierarchy-list">
<li data-id="1" class="wphierarchy-item">Виджет 1 <button class="wphierarchy-load">Показать вложенные</button></li>
<li data-id="2" class="wphierarchy-item">Виджет 2 <button class="wphierarchy-load">Показать вложенные</button></li>
</ul>
</div>
<script>
jQuery(document).ready(function($) {
$('#wphierarchy-widgets').on('click', '.wphierarchy-load', function() {
var btn = $(this);
var li = btn.closest('.wphierarchy-item');
var parentId = li.data('id');
// Если дочерние уже загружены, переключаем видимость
if (li.children('ul').length) {
li.children('ul').toggle();
return;
}
btn.prop('disabled', true).text('Загрузка...');
$.post(wphierarchy_ajax.ajax_url, {
action: 'wphierarchy_get_child_widgets',
nonce: wphierarchy_ajax.nonce,
parent_id: parentId
}, function(response) {
if (response.length) {
var ul = $('<ul></ul>');
$.each(response, function(i, widget) {
var liChild = $('<li></li>').addClass('wphierarchy-item').attr('data-id', widget.id).text(widget.title);
var btnLoad = $('<button>Показать вложенные</button>').addClass('wphierarchy-load');
liChild.append(' ').append(btnLoad);
ul.append(liChild);
});
li.append(ul);
} else {
alert('Вложенных виджетов нет');
}
btn.prop('disabled', false).text('Показать вложенные');
});
});
});
</script>
Не забудьте локализовать скрипт для передачи ajax_url и nonce:
function wphierarchy_enqueue_scripts() {
wp_enqueue_script('jquery');
wp_enqueue_script('wphierarchy-script', get_template_directory_uri() . '/js/wphierarchy.js', ['jquery'], null, true);
wp_localize_script('wphierarchy-script', 'wphierarchy_ajax', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wphierarchy_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'wphierarchy_enqueue_scripts');
Оптимизация и расширение функционала иерархии виджетов
Реализованный базовый пример можно существенно расширить:
- Добавить кэширование результатов AJAX, чтобы не перегружать сервер повторными запросами.
- Использовать REST API вместо admin-ajax.php для более современной архитектуры.
- Подключить кастомные поля и метаданные к виджетам для более информативного вывода.
- Реализовать drag-and-drop интерфейс для изменения иерархии прямо на фронтенде.
- Интегрировать с плагинами вроде Clearfy Pro для оптимизации загрузки и безопасности.
Такой подход позволит создавать удобные, масштабируемые интерфейсы с многоуровневыми виджетами и при этом держать производительность на высоком уровне.
Пример функции для получения дочерних виджетов из БД
function wphierarchy_get_widgets_by_parent($parent_id) {
global $wpdb;
$table = $wpdb->prefix . 'wphierarchy_widgets';
return $wpdb->get_results($wpdb->prepare("SELECT * FROM $table WHERE parent_id = %d", $parent_id));
}
Работа с БД позволит хранить иерархию в удобном формате и быстро получать данные.
Заключение
Создание иерархии виджетов с динамической подгрузкой — полезный прием для сложных сайтов на WordPress. Он позволяет уменьшить нагрузку на сервер и улучшить взаимодействие с пользователем. В статье приведен полный пример реализации на AJAX и PHP, который легко адаптировать под свои задачи.
Для расширения функционала рекомендую изучить REST API WordPress и современные JavaScript-фреймворки, а также обратить внимание на плагины оптимизации, например, Clearfy Pro.