Создание динамического табличного каталога в WordPress — задача, с которой часто сталкиваются разработчики и владельцы сайтов, желающие упорядочить и отобразить данные в удобном формате. В этой статье мы разберем, как создать такой каталог с помощью шорткода, используя WP_Query и кастомные поля, а также рассмотрим оптимизацию и примеры интеграции с популярными плагинами.
Почему динамические каталоги лучше статических таблиц
Статические таблицы — это HTML или Excel-файлы, встроенные напрямую на страницу. Они не обновляются автоматически, требуют ручного редактирования при изменении данных и плохо масштабируются при большом объеме информации. Динамические каталоги автоматически подгружают актуальные данные из базы, что обеспечивает:
- Автоматическое обновление контента при изменении данных;
- Фильтрацию, сортировку и пагинацию;
- Возможность расширения функционала (например, интеграция с WooCommerce или кастомными типами записей);
- Удобство управления через админку WordPress.
Для реализации динамических таблиц мы будем использовать шорткоды, которые можно вставить в любую запись или страницу.
Создание кастомного шорткода для табличного каталога
Начнем с создания простого шорткода, который выводит таблицу с данными из кастомного типа записей catalog_item. Предположим, что у каждого товара есть кастомные поля: price, sku и availability.
Добавьте следующий код в файл functions.php вашей темы или в отдельный плагин:
function wpcatalog_get_dynamic_catalog_shortcode($atts) {
$atts = shortcode_atts(array(
'posts_per_page' => 10,
'paged' => 1
), $atts, 'wpcatalog_dynamic_catalog');
$paged = max(1, intval(get_query_var('paged')));
$args = array(
'post_type' => 'catalog_item',
'posts_per_page' => intval($atts['posts_per_page']),
'paged' => $paged
);
$query = new WP_Query($args);
if (!$query->have_posts()) {
return '<p>Каталог пуст.</p>';
}
$output = '<table class="wpcatalog-table">';
$output .= '<thead><tr><th>Название</th><th>Артикул</th><th>Цена</th><th>Наличие</th></tr></thead>';
$output .= '<tbody>';
while ($query->have_posts()) {
$query->the_post();
$sku = get_post_meta(get_the_ID(), 'sku', true);
$price = get_post_meta(get_the_ID(), 'price', true);
$availability = get_post_meta(get_the_ID(), 'availability', true);
$output .= '<tr>';
$output .= '<td>' . get_the_title() . '</td>';
$output .= '<td>' . esc_html($sku) . '</td>';
$output .= '<td>' . esc_html($price) . ' ₽</td>';
$output .= '<td>' . esc_html($availability) . '</td>';
$output .= '</tr>';
}
$output .= '</tbody></table>';
// Пагинация
$big = 999999999; // уникальное число для замены
$pagination = paginate_links(array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => $paged,
'total' => $query->max_num_pages,
'type' => 'list'
));
wp_reset_postdata();
return $output . $pagination;
}
add_shortcode('wpcatalog_dynamic_catalog', 'wpcatalog_get_dynamic_catalog_shortcode');Этот шорткод выводит таблицу с пагинацией и данными из пользовательских полей. Для отображения каталога вставьте в контент страницы [wpcatalog_dynamic_catalog posts_per_page=10].
Добавление фильтров для каталога
Для повышения удобства пользователя полезно добавить фильтры по цене, наличию или другим параметрам. Для этого расширим шорткод, добавив HTML-форму и обработку GET-параметров.
Пример расширения функции:
function wpcatalog_get_dynamic_catalog_shortcode($atts) {
$atts = shortcode_atts(array(
'posts_per_page' => 10
), $atts, 'wpcatalog_dynamic_catalog');
$paged = max(1, intval(get_query_var('paged')));
// Получаем фильтры из GET
$min_price = isset($_GET['min_price']) ? floatval($_GET['min_price']) : 0;
$max_price = isset($_GET['max_price']) ? floatval($_GET['max_price']) : 0;
$availability = isset($_GET['availability']) ? sanitize_text_field($_GET['availability']) : '';
$meta_query = array('relation' => 'AND');
if ($min_price > 0) {
$meta_query[] = array(
'key' => 'price',
'value' => $min_price,
'compare' => '>=',
'type' => 'NUMERIC'
);
}
if ($max_price > 0) {
$meta_query[] = array(
'key' => 'price',
'value' => $max_price,
'compare' => '<=',
'type' => 'NUMERIC'
);
}
if (!empty($availability)) {
$meta_query[] = array(
'key' => 'availability',
'value' => $availability,
'compare' => '='
);
}
$args = array(
'post_type' => 'catalog_item',
'posts_per_page' => intval($atts['posts_per_page']),
'paged' => $paged,
'meta_query' => $meta_query
);
$query = new WP_Query($args);
// Форма фильтра
$output = '<form method="get" class="wpcatalog-filter">';
$output .= '<label>Мин. цена: <input type="number" name="min_price" value="' . esc_attr($min_price) . '" /></label> ';
$output .= '<label>Макс. цена: <input type="number" name="max_price" value="' . esc_attr($max_price) . '" /></label> ';
$output .= '<label>Наличие: <select name="availability">';
$output .= '<option value="">Все</option>';
$output .= '<option value="В наличии"' . selected($availability, 'В наличии', false) . '>В наличии</option>';
$output .= '<option value="Нет в наличии"' . selected($availability, 'Нет в наличии', false) . '>Нет в наличии</option>';
$output .= '</select></label> ';
$output .= '<button type="submit">Фильтровать</button>';
$output .= '</form>';
if (!$query->have_posts()) {
return $output . '<p>По вашему запросу ничего не найдено.</p>';
}
$output .= '<table class="wpcatalog-table">';
$output .= '<thead><tr><th>Название</th><th>Артикул</th><th>Цена</th><th>Наличие</th></tr></thead>';
$output .= '<tbody>';
while ($query->have_posts()) {
$query->the_post();
$sku = get_post_meta(get_the_ID(), 'sku', true);
$price = get_post_meta(get_the_ID(), 'price', true);
$availability_meta = get_post_meta(get_the_ID(), 'availability', true);
$output .= '<tr>';
$output .= '<td>' . get_the_title() . '</td>';
$output .= '<td>' . esc_html($sku) . '</td>';
$output .= '<td>' . esc_html($price) . ' ₽</td>';
$output .= '<td>' . esc_html($availability_meta) . '</td>';
$output .= '</tr>';
}
$output .= '</tbody></table>';
// Пагинация
$big = 999999999;
$pagination = paginate_links(array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => $paged,
'total' => $query->max_num_pages,
'add_args' => $_GET,
'type' => 'list'
));
wp_reset_postdata();
return $output . $pagination;
}Такой подход дает пользователю возможность отфильтровать товары по цене и наличию без установки дополнительных плагинов.
Интеграция с плагином Clearfy для оптимизации каталога
Если каталог содержит большое количество товаров, важно оптимизировать запросы и скорость загрузки страниц. Плагин Clearfy поможет оптимизировать работу сайта, отключив ненужные скрипты и функции WordPress, что снизит нагрузку и ускорит работу каталога.
Для улучшения производительности можно использовать встроенные возможности Clearfy:
- Оптимизация CSS и JS;
- Отключение неиспользуемых функций WordPress;
- Кэширование страниц и запросов;
- Оптимизация базы данных.
Использование Clearfy рекомендуется на сайтах с большими каталогами и сложными запросами, чтобы избежать тормозов и сбоев.
Пример оформления таблицы и CSS для удобства чтения
Для улучшения восприятия каталога добавим базовые стили. Добавьте в файл стилей темы или в раздел «Дополнительные стили» следующий CSS:
.wpcatalog-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.wpcatalog-table th, .wpcatalog-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.wpcatalog-table th {
background-color: #f4f4f4;
}
.wpcatalog-filter {
margin-bottom: 15px;
}
.wpcatalog-filter label {
margin-right: 15px;
}
.wpcatalog-filter input, .wpcatalog-filter select {
padding: 4px 6px;
margin-left: 5px;
}Это сделает таблицу читабельной и удобной для пользователя.
Заключение и рекомендации
Создание динамического табличного каталога с помощью кастомных шорткодов — эффективное решение для сайтов на WordPress, где важна актуальность и удобство работы с данными. Благодаря возможностям WP_Query, кастомным полям и расширенной фильтрации можно создать гибкий инструмент под любые задачи.
Для более сложных каталогов рекомендуем рассмотреть плагин WPRemark, который расширяет возможности работы с отзывами и данными товаров, а также облегчает создание интерактивных элементов.
Если требуется расширенная фильтрация и удобное управление, можно также использовать плагин Quizle для создания пошаговых фильтров и опросов.