Создание персонализированного виджета WordPress

В этой статье мы рассмотрим, как создать собственный виджет WordPress с уникальной функциональностью, который можно использовать для вывода контента в сайдбаре или других виджетных областях вашей темы. Создание виджетов — важный навык для разработчика, который позволяет добавлять интерактивные и полезные элементы на сайт без использования множества плагинов.

Что такое виджет WordPress и зачем создавать свой?

Виджеты в WordPress — это небольшие блоки с содержимым, которые можно размещать в специально отведённых областях сайта, например, сайдбаре, футере или других местах, поддерживающих виджеты. Обычно темы и плагины поставляются с набором стандартных виджетов, но иногда требуется уникальное решение, которое именно под ваши задачи.

Свои виджеты полезно создавать, если нужно:

  • Показывать динамический контент с особыми настройками;
  • Интегрировать внешние сервисы;
  • Добавлять сложную логику вывода данных;
  • Оптимизировать работу сайта, уменьшая количество плагинов.

Кроме того, собственный виджет можно легко распространять и повторно использовать на других сайтах.

Основные шаги создания виджета в WordPress

В основе создания виджета лежит наследование от класса WP_Widget и переопределение нескольких обязательных методов. Давайте разберём каждый по порядку.

Регистрация виджета

Сначала нужно зарегистрировать наш виджет, чтобы WordPress знал о его существовании. Для этого используем хук widgets_init и функцию register_widget().

function wporder_register_custom_widget() {
    register_widget('WPOrder_Custom_Widget');
}
add_action('widgets_init', 'wporder_register_custom_widget');

Класс виджета

Далее создаём класс виджета, наследующий WP_Widget. Основные методы, которые нужно реализовать:

  • __construct() — инициализация и настройка виджета;
  • widget() — вывод содержимого виджета на фронтенде;
  • form() — вывод формы настроек в админке;
  • update() — обработка и сохранение данных из формы настроек.
class WPOrder_Custom_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wporder_custom_widget',
            'WPOrder: Персонализированный виджет',
            ['description' => 'Пример собственного виджета с настройками']
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        $title = apply_filters('widget_title', $instance['title'] ?? '');
        if (!empty($title)) {
            echo $args['before_title'] . esc_html($title) . $args['after_title'];
        }

        // Основной вывод виджета
        echo '<p>Добро пожаловать в персонализированный виджет WPOrder!</p>';

        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = $instance['title'] ?? '';
        ?>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('title')); ?>">Заголовок:</label>
            <input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" 
                   name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" 
                   value="<?php echo esc_attr($title); ?>">
        </p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = [];
        $instance['title'] = (!empty($new_instance['title'])) ? sanitize_text_field($new_instance['title']) : '';
        return $instance;
    }
}

Добавление расширенной функциональности в виджет

Чтобы виджет был полезнее, можно добавить дополнительные настройки и динамический вывод. Например, сделаем вывод списка последних заказов WooCommerce (если он установлен).

Получение последних заказов WooCommerce

Для примера используем функцию WP_Query с кастомным типом записи shop_order. Добавим в виджет поле для выбора количества заказов.

public function widget($args, $instance) {
    echo $args['before_widget'];
    $title = apply_filters('widget_title', $instance['title'] ?? '');
    $number = !empty($instance['number']) ? absint($instance['number']) : 5;

    if (!empty($title)) {
        echo $args['before_title'] . esc_html($title) . $args['after_title'];
    }

    if (class_exists('WooCommerce')) {
        $query = new WP_Query([
            'post_type' => 'shop_order',
            'posts_per_page' => $number,
            'post_status' => ['wc-completed', 'wc-processing'],
        ]);

        if ($query->have_posts()) {
            echo '<ul>';
            while ($query->have_posts()) {
                $query->the_post();
                $order = wc_get_order(get_the_ID());
                echo '<li>Заказ #' . $order->get_id() . ' — ' . wc_price($order->get_total()) . '</li>';
            }
            echo '</ul>';
            wp_reset_postdata();
        } else {
            echo '<p>Заказы не найдены.</p>';
        }
    } else {
        echo '<p>WooCommerce не установлен.</p>';
    }

    echo $args['after_widget'];
}

Добавление поля настроек для количества заказов

Обновим форму настроек и метод сохранения данных:

public function form($instance) {
    $title = $instance['title'] ?? '';
    $number = $instance['number'] ?? 5;
    ?>
    <p>
        <label for="<?php echo esc_attr($this->get_field_id('title')); ?>">Заголовок:</label>
        <input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" 
               name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" 
               value="<?php echo esc_attr($title); ?>">
    </p>
    <p>
        <label for="<?php echo esc_attr($this->get_field_id('number')); ?>">Количество заказов для вывода:</label>
        <input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('number')); ?>" 
               name="<?php echo esc_attr($this->get_field_name('number')); ?>" type="number" step="1" min="1" 
               value="<?php echo esc_attr($number); ?>" size="3">
    </p>
    <?php
}

public function update($new_instance, $old_instance) {
    $instance = [];
    $instance['title'] = (!empty($new_instance['title'])) ? sanitize_text_field($new_instance['title']) : '';
    $instance['number'] = (!empty($new_instance['number'])) ? absint($new_instance['number']) : 5;
    return $instance;
}

Советы по отладке и расширению виджета

При разработке виджета важно тестировать его в разных темах и с разными плагинами, чтобы избежать конфликтов и ошибок. Вот несколько рекомендаций:

  • Используйте функции WordPress для безопасного вывода данных — esc_html(), esc_attr(), wp_kses_post();
  • Добавляйте проверки наличия функций и классов, например, WooCommerce, чтобы избежать фатальных ошибок;
  • Реализуйте кэширование, если виджет делает дорогие запросы к базе данных;
  • Добавляйте возможность локализации строк через __() и _e();
  • Документируйте код и используйте понятные имена, как в примерах с префиксом WPOrder_ для уникальности.

Дополнительные полезные плагины для работы с виджетами

Если вы хотите расширить возможности виджетов без разработки с нуля, обратите внимание на следующие плагины:

  • Widget Options — добавляет гибкие настройки виджетов, включая условия показа и стили;
  • Custom Sidebars — позволяет создавать новые области для виджетов и настраивать их отображение на разных страницах;
  • SiteOrigin Widgets Bundle — набор удобных виджетов с расширенными настройками и поддержкой page builder;
  • Black Studio TinyMCE Widget — позволяет создавать виджеты с визуальным редактором.

Однако собственный виджет всегда даёт максимальную гибкость и контроль.

Заключение

Создание собственного виджета WordPress — несложный, но мощный способ добавить уникальный функционал вашему сайту. В этой статье разобраны основные шаги, а также показан пример виджета с динамическим выводом последних заказов WooCommerce и настройками. Используйте этот пример как основу для своих задач и расширяйте возможности вашего сайта с помощью кастомных виджетов.

Как отключить автообновление плагинов WordPress
12.03.2026
WooCommerce: решение проблемы с отправкой писем после оформления заказа
12.06.2026
Автоматическое создание и отправка PDF счетов в WordPress при оформлении заказа
02.03.2026
Оптимизация обработки заказов в WordPress: лучшие практики и примеры кода
07.11.2025
WooCommerce: решение проблемы с отправкой писем после оформления заказа
07.07.2026