В современных интерфейсах часто требуется создавать списки с возможностью перетаскивания элементов и их вложенности (nestable списки). В WordPress такая функциональность может понадобиться для управления меню, сортировки элементов в админке или на фронтенде сайта. В этой статье мы подробно разберем, как реализовать nestable списки в WordPress, используя как готовые плагины, так и пользовательский код с JavaScript-библиотекой jQuery Nestable.
Что такое nestable список и зачем он нужен в WordPress
Nestable список — это список, элементы которого можно перетаскивать мышью (drag-and-drop), а также создавать вложенные подсписки. Такая структура удобна для визуальной организации данных, например, для меню, FAQ, сортировки товаров или постов.
В WordPress стандартно есть меню с drag-and-drop в админке, но иногда нужно реализовать подобный функционал на странице или в собственном плагине с кастомными типами записей. Для этого можно использовать готовые решения или написать свой код.
Основные возможности nestable списков:
- Перетаскивание элементов для изменения порядка
- Создание вложенности — элементов, вложенных друг в друга
- Сохранение и загрузка структуры через AJAX
Использование плагинов для создания nestable списков
Для тех, кто не хочет писать код с нуля, есть несколько плагинов, которые добавляют функционал drag-and-drop и nestable списков прямо в WordPress.
Плагин WP Nestable
Этот бесплатный плагин добавляет shortcode для вывода nestable списков с поддержкой drag-and-drop. Удобен для простых задач и быстрого старта.
Основные возможности WP Nestable:
- Поддержка вложенных списков
- Сохранение структуры через AJAX
- Настраиваемый вывод элементов
После установки плагина можно вставить shortcode [wpnestable] на страницу, и список будет интерактивным.
Плагин Nested Pages
Если вам нужно управлять структурой страниц в админке с drag-and-drop, Nested Pages — отличный выбор. Он упрощает организацию страниц и вложенных элементов.
Однако этот плагин больше ориентирован на структуру страниц, а не на произвольные списки на фронтенде.
Реализация nestable списка с помощью jQuery Nestable и собственного кода
Если вы хотите полный контроль, можно использовать популярную библиотеку jQuery Nestable. Она легкая, простая и хорошо документирована.
Давайте рассмотрим пример, как интегрировать эту библиотеку в WordPress и сохранить структуру списка.
Подключение скриптов и стилей
Для начала зарегистрируем и подключим jQuery Nestable в functions.php вашей темы или плагина:
function wptask_enqueue_nestable_scripts() {
wp_enqueue_style('wptask-nestable-css', 'https://cdn.jsdelivr.net/npm/nestable2@1.6.0/jquery.nestable.min.css');
wp_enqueue_script('wptask-nestable-js', 'https://cdn.jsdelivr.net/npm/nestable2@1.6.0/jquery.nestable.min.js', ['jquery'], null, true);
wp_enqueue_script('wptask-nestable-init', get_template_directory_uri() . '/js/wptask-nestable-init.js', ['wptask-nestable-js'], null, true);
wp_localize_script('wptask-nestable-init', 'wptask_ajax_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wptask_save_nestable')
]);
}
add_action('wp_enqueue_scripts', 'wptask_enqueue_nestable_scripts');В этом примере мы подключаем CSS и JS из CDN, а также свой скрипт wptask-nestable-init.js, где будем инициализировать список и обрабатывать сохранение.
HTML-разметка для nestable списка
Добавим на страницу следующий HTML для списка:
<div class="dd" id="wptask-nestable">
<ol class="dd-list">
<li class="dd-item" data-id="1"><div class="dd-handle">Элемент 1</div></li>
<li class="dd-item" data-id="2">
<div class="dd-handle">Элемент 2</div>
<ol class="dd-list">
<li class="dd-item" data-id="3"><div class="dd-handle">Вложенный элемент 3</div></li>
</ol>
</li>
<li class="dd-item" data-id="4"><div class="dd-handle">Элемент 4</div></li>
</ol>
</div>
<button id="wptask-save-nestable">Сохранить порядок</button>Каждый элемент имеет класс dd-item и уникальный data-id, что позволяет библиотеке отслеживать структуру.
JavaScript для инициализации и сохранения данных
Создадим файл wptask-nestable-init.js со следующим содержимым:
jQuery(document).ready(function($) {
$('#wptask-nestable').nestable();
$('#wptask-save-nestable').on('click', function() {
var serializedData = $('#wptask-nestable').nestable('serialize');
$.ajax({
url: wptask_ajax_obj.ajax_url,
type: 'POST',
data: {
action: 'wptask_save_nestable',
nonce: wptask_ajax_obj.nonce,
data: serializedData
},
success: function(response) {
alert('Порядок сохранён!');
},
error: function() {
alert('Ошибка при сохранении');
}
});
});
});Этот скрипт инициализирует nestable список и отправляет сериализованную структуру на сервер по AJAX при нажатии кнопки.
Обработка AJAX-запроса в WordPress
Добавим в functions.php обработчик AJAX:
function wptask_save_nestable() {
check_ajax_referer('wptask_save_nestable', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error('Доступ запрещён');
}
$data = isset($_POST['data']) ? wp_unslash($_POST['data']) : '';
if (!$data) {
wp_send_json_error('Нет данных для сохранения');
}
// Здесь можно сохранить структуру в базу данных, например, в опции
update_option('wptask_nestable_structure', $data);
wp_send_json_success('Структура сохранена');
}
add_action('wp_ajax_wptask_save_nestable', 'wptask_save_nestable');В этом примере мы проверяем nonce, права пользователя и сохраняем структуру в опцию WordPress. В реальном проекте можно сохранять данные в отдельные поля, метаполя или кастомные таблицы.
Как вывести сохранённую структуру на сайте
Чтобы вывести сохранённый nestable список, нужно получить данные из базы и сгенерировать HTML с правильными классами.
Пример функции для рендеринга списка из массива:
function wptask_render_nestable_list(array $items) {
$html = '<ol class="dd-list">';
foreach ($items as $item) {
$html .= '<li class="dd-item" data-id="' . esc_attr($item['id']) . '">';
$html .= '<div class="dd-handle">' . esc_html($item['title']) . '</div>';
if (!empty($item['children'])) {
$html .= wptask_render_nestable_list($item['children']);
}
$html .= '</li>';
}
$html .= '</ol>';
return $html;
}Перед вызовом функции необходимо десериализовать JSON из опции:
$saved = get_option('wptask_nestable_structure');
$items = json_decode($saved, true);
echo '<div class="dd" id="wptask-nestable">';
echo wptask_render_nestable_list($items);
echo '</div>';Полезные советы и рекомендации
Оптимизация производительности
При большом количестве элементов стоит учитывать производительность как на фронтенде, так и при сохранении структуры. AJAX-запросы должны быть быстро обработаны, а вывод — кеширован.
Безопасность данных
Всегда используйте nonce и проверяйте права пользователя при обработке AJAX-запросов, чтобы избежать уязвимостей.
Расширяемость
Такую реализацию можно расширять, добавляя поля к элементам, например, иконки, описания или действия. Для этого придется модифицировать HTML и JavaScript, а также хранить дополнительные данные.