Как создать динамические табличные каталоги в WordPress с помощью шорткода

Создание динамического табличного каталога в 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 для создания пошаговых фильтров и опросов.

Автоматическое изменение стоимости товаров в WooCommerce при снижении остатка на складе
13.05.2026
Как добавить автоматическое удаление старых черновых комментариев в WordPress
12.02.2026
Как создать собственную таблицу в WordPress без плагинов
21.11.2025
Как очистить базу данных WordPress от старых meta данных и оптимизировать сайт
13.03.2026
Оптимизация загрузки изображений в WordPress для повышения скорости сайта
11.12.2025