В WordPress часто возникает задача отображать данные в виде таблиц, причем желательно, чтобы эти таблицы были динамическими — например, подгружали данные без перезагрузки страницы, позволяли фильтровать или сортировать информацию. В этой статье мы разберем, как создать динамическую таблицу с применением шорткодов и AJAX-запросов, чтобы пользователи сайта получали актуальные данные на лету.
Почему динамические таблицы важны для WordPress
Таблицы — удобный способ структурировать информацию, будь то списки товаров, расписания, отчеты или аналитика. Статические таблицы — это просто HTML-код, который не меняется без обновления страницы. А динамические позволяют:
- Обновлять содержимое таблицы без перезагрузки страницы
- Загружать большие объемы данных по частям (пагинация)
- Добавлять фильтры и сортировку на стороне сервера
- Улучшать пользовательский опыт и скорость работы сайта
Для реализации динамических таблиц в WordPress оптимально использовать шорткоды, которые легко вставлять в любой пост или страницу, а также AJAX для асинхронной загрузки данных.
Создаем шорткод для вывода таблицы
Начнем с простого шорткода, который выводит базовую таблицу с данными, полученными из базы данных WordPress. Например, сделаем таблицу, которая выводит последние 10 записей из определенной категории.
function wprobot_dynamic_table_shortcode($atts) {
global $wpdb;
$atts = shortcode_atts(array(
'category' => '',
'posts_per_page' => 10
), $atts, 'wprobot_dynamic_table');
$category = sanitize_text_field($atts['category']);
$posts_per_page = intval($atts['posts_per_page']);
$query = $wpdb->prepare(
"SELECT p.ID, p.post_title, p.post_date FROM {$wpdb->posts} p
INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)
INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN {$wpdb->terms} t ON (tt.term_id = t.term_id)
WHERE p.post_type = 'post' AND p.post_status = 'publish' AND t.slug = %s
ORDER BY p.post_date DESC LIMIT %d",
$category, $posts_per_page
);
$results = $wpdb->get_results($query);
if (empty($results)) {
return '<p>Нет записей для отображения.</p>';
}
$output = '<table class="wprobot-table"><thead><tr><th>Заголовок</th><th>Дата публикации</th></tr></thead><tbody>';
foreach ($results as $row) {
$url = get_permalink($row->ID);
$output .= '<tr><td><a href="'. esc_url($url) .'">'. esc_html($row->post_title) .'</a></td><td>'. esc_html(date('d.m.Y', strtotime($row->post_date))) .'</td></tr>';
}
$output .= '</tbody></table>';
return $output;
}
add_shortcode('wprobot_dynamic_table', 'wprobot_dynamic_table_shortcode');Этот код создает шорткод [wprobot_dynamic_table category="novosti" posts_per_page="10"], который выводит таблицу с последними 10 постами из категории «novosti».
Добавляем AJAX для динамической подгрузки данных
Чтобы таблица была по-настоящему динамической, сделаем подгрузку данных по AJAX, например, добавим пагинацию без перезагрузки страницы. В этом примере мы сделаем кнопку «Загрузить еще», которая будет подгружать следующие записи.
Шаг 1. Добавляем скрипт и локализацию
function wprobot_enqueue_scripts() {
wp_enqueue_script('wprobot-ajax-table', get_stylesheet_directory_uri() . '/js/wprobot-ajax-table.js', array('jquery'), '1.0', true);
wp_localize_script('wprobot-ajax-table', 'wprobot_ajax_obj', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wprobot_ajax_nonce')
));
}
add_action('wp_enqueue_scripts', 'wprobot_enqueue_scripts');Этот код подключает JS-файл и передает в него URL для AJAX-запросов и nonce для безопасности.
Шаг 2. Обрабатываем AJAX-запросы в PHP
function wprobot_load_more_posts() {
check_ajax_referer('wprobot_ajax_nonce', 'security');
$paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$posts_per_page = 10;
if ($paged < 1) $paged = 1;
$offset = ($paged - 1) * $posts_per_page;
global $wpdb;
$query = $wpdb->prepare(
"SELECT p.ID, p.post_title, p.post_date FROM {$wpdb->posts} p
INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)
INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN {$wpdb->terms} t ON (tt.term_id = t.term_id)
WHERE p.post_type = 'post' AND p.post_status = 'publish' AND t.slug = %s
ORDER BY p.post_date DESC LIMIT %d, %d",
$category, $offset, $posts_per_page
);
$results = $wpdb->get_results($query);
if (empty($results)) {
wp_send_json_error('Нет больше записей');
}
$output = '';
foreach ($results as $row) {
$url = get_permalink($row->ID);
$output .= '<tr><td><a href="'. esc_url($url) .'">'. esc_html($row->post_title) .'</a></td><td>'. esc_html(date('d.m.Y', strtotime($row->post_date))) .'</td></tr>';
}
wp_send_json_success($output);
}
add_action('wp_ajax_wprobot_load_more', 'wprobot_load_more_posts');
add_action('wp_ajax_nopriv_wprobot_load_more', 'wprobot_load_more_posts');Шаг 3. Создаем JavaScript для обработки клика
Файл js/wprobot-ajax-table.js:
jQuery(document).ready(function($) {
var paged = 2;
var category = $('.wprobot-table').data('category');
$('#wprobot-load-more').on('click', function(e) {
e.preventDefault();
var button = $(this);
button.prop('disabled', true).text('Загрузка...');
$.ajax({
url: wprobot_ajax_obj.ajax_url,
type: 'POST',
data: {
action: 'wprobot_load_more',
paged: paged,
category: category,
security: wprobot_ajax_obj.nonce
},
success: function(response) {
if (response.success) {
$('.wprobot-table tbody').append(response.data);
paged++;
button.prop('disabled', false).text('Загрузить еще');
} else {
button.text('Больше записей нет');
button.prop('disabled', true);
}
},
error: function() {
button.prop('disabled', false).text('Ошибка загрузки');
}
});
});
});Подключаем пагинацию и выводим кнопку
Обновим шорткод, чтобы таблица содержала data-атрибут с категорией и кнопку для загрузки данных:
function wprobot_dynamic_table_shortcode($atts) {
global $wpdb;
$atts = shortcode_atts(array(
'category' => '',
'posts_per_page' => 10
), $atts, 'wprobot_dynamic_table');
$category = sanitize_text_field($atts['category']);
$posts_per_page = intval($atts['posts_per_page']);
$query = $wpdb->prepare(
"SELECT p.ID, p.post_title, p.post_date FROM {$wpdb->posts} p
INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)
INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN {$wpdb->terms} t ON (tt.term_id = t.term_id)
WHERE p.post_type = 'post' AND p.post_status = 'publish' AND t.slug = %s
ORDER BY p.post_date DESC LIMIT %d",
$category, $posts_per_page
);
$results = $wpdb->get_results($query);
if (empty($results)) {
return '<p>Нет записей для отображения.</p>';
}
$output = '<table class="wprobot-table" data-category="'. esc_attr($category) .'"><thead><tr><th>Заголовок</th><th>Дата публикации</th></tr></thead><tbody>';
foreach ($results as $row) {
$url = get_permalink($row->ID);
$output .= '<tr><td><a href="'. esc_url($url) .'">'. esc_html($row->post_title) .'</a></td><td>'. esc_html(date('d.m.Y', strtotime($row->post_date))) .'</td></tr>';
}
$output .= '</tbody></table>';
$output .= '<button id="wprobot-load-more" type="button">Загрузить еще</button>';
return $output;
}
add_shortcode('wprobot_dynamic_table', 'wprobot_dynamic_table_shortcode');Советы по оптимизации и безопасности
При работе с AJAX и базой данных важно соблюдать несколько правил:
- Используйте
wp_nonceдля защиты AJAX-запросов от CSRF-атак. - Обязательно фильтруйте и экранируйте все входящие данные с помощью функций
sanitize_text_field,intval,esc_html,esc_url. - Для сложных и больших таблиц рассмотрите использование специализированных плагинов, например, ABC Pagination для удобной навигации по страницам.
- Кешируйте результаты запросов там, где это возможно, чтобы снизить нагрузку на сервер.
Примеры полезных плагинов для работы с таблицами в WordPress
Если не хочется писать код с нуля, можно использовать плагины, которые позволяют создавать и управлять таблицами с динамическими функциями:
- TablePress — один из самых популярных плагинов для создания таблиц. Позволяет импортировать данные, добавлять сортировку и фильтры.
- WPDataTables — мощный инструмент для работы с большими наборами данных, поддерживает AJAX-подгрузку и интеграцию с внешними источниками.
- ABC Pagination — улучшает отображение списков и таблиц с постраничной навигацией, полезен для динамических таблиц с большим количеством записей. Подробнее на wpshop.ru.
Заключение: динамические таблицы — шаг к удобству пользователей
Создание динамических таблиц с помощью шорткодов и AJAX — отличный способ сделать сайт на WordPress более интерактивным и удобным для посетителей. Вы можете самостоятельно расширять функционал, добавлять фильтры, сортировку, пагинацию и многое другое. Приведенные примеры — базовый фундамент, который легко адаптируется под любые задачи.