Как создать собственный виджет в WordPress: практическое руководство

Что такое виджеты в WordPress и зачем создавать собственные

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

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

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

Основы создания виджета в WordPress: класс WP_Widget и его методы

Для создания виджета в WordPress используется класс WP_Widget, от которого необходимо наследоваться. Основные методы, которые нужно реализовать в вашем классе:

  • __construct() — инициализация виджета, название и описание;
  • widget($args, $instance) — вывод содержимого виджета на сайт;
  • form($instance) — форма настроек виджета в админке;
  • update($new_instance, $old_instance) — обработка и сохранение настроек.

При регистрации виджета используется функция register_widget(). Обычно регистрацию делают через хук widgets_init.

Пример создания простого виджета с названием и описанием

Ниже пример минимального класса виджета для сайта wpsell.ru:

class WPSELL_Widget_Hello extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wpsell_widget_hello',
            'WPSELL: Приветствие',
            ['description' => 'Простой виджет для вывода приветствия']
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        echo '<h3>Привет от WPSELL!</h3>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        echo '<p>Настроек нет</p>';
    }

    public function update($new_instance, $old_instance) {
        return $old_instance;
    }
}

function wpsell_register_widget() {
    register_widget('WPSELL_Widget_Hello');
}
add_action('widgets_init', 'wpsell_register_widget');

Этот код создаст простой виджет, который выведет статическое приветствие. Добавьте его в файл functions.php вашей темы или в отдельный плагин.

Добавление настроек в виджет: пользовательские поля и сохранение данных

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

Для этого редактируем методы form() и update(), а в widget() выводим динамический текст.

Пример расширенного виджета с настройками

class WPSELL_Widget_CustomGreeting extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wpsell_widget_greeting',
            'WPSELL: Кастомное приветствие',
            ['description' => 'Виджет с настраиваемым приветствием']
        );
    }

    public function widget($args, $instance) {
        $greeting = !empty($instance['greeting']) ? $instance['greeting'] : 'Здравствуйте!';
        echo $args['before_widget'];
        echo '<h3>' . esc_html($greeting) . '</h3>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        $greeting = !empty($instance['greeting']) ? $instance['greeting'] : '';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('greeting'); ?>">Текст приветствия:</label>
            <input class="widefat" id="<?php echo $this->get_field_id('greeting'); ?>" name="<?php echo $this->get_field_name('greeting'); ?>" type="text" value="<?php echo esc_attr($greeting); ?>" />
        </p>
        <?php
    }

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

function wpsell_register_custom_greeting_widget() {
    register_widget('WPSELL_Widget_CustomGreeting');
}
add_action('widgets_init', 'wpsell_register_custom_greeting_widget');

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

Использование популярных плагинов для управления виджетами и улучшения функционала

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

  • Widget Logic — добавляет условные теги, позволяющие показывать виджеты только на определённых страницах или при заданных условиях.
  • Custom Sidebars — позволяет создавать и управлять неограниченным количеством сайдбаров с различным набором виджетов.
  • SiteOrigin Widgets Bundle — набор виджетов с богатым функционалом и визуальной настройкой.

Эти плагины отлично дополняют стандартные виджеты и помогают решать сложные задачи без программирования.

Советы по оптимизации и безопасности собственных виджетов

При разработке виджетов важно соблюдать несколько правил:

  • Используйте функции очистки и экранирования данных, например, sanitize_text_field() и esc_html(), чтобы избежать XSS-уязвимостей.
  • Не загружайте ресурсы (CSS, JS) без необходимости. Если нужны стили, подключайте их через wp_enqueue_scripts с проверкой, что они загружаются только на страницах, где используется виджет.
  • Старайтесь не перегружать виджет тяжелыми запросами к базе. Если нужно, используйте кеширование с помощью Transients API.
  • Тестируйте виджет как на разных темах, так и с другими плагинами, чтобы избежать конфликтов.

Соблюдение этих рекомендаций поможет сделать виджет стабильным, быстрым и безопасным.

Пример расширенного виджета с использованием WP_Query и кешированием

Допустим, нам нужно вывести последние 3 записи из определённой категории. Для этого используем класс WP_Query и кеширование с помощью функции set_transient.

class WPSELL_Widget_RecentPosts extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wpsell_widget_recent_posts',
            'WPSELL: Последние записи из категории',
            ['description' => 'Выводит последние записи из выбранной категории']
        );
    }

    public function widget($args, $instance) {
        $cat_id = !empty($instance['cat_id']) ? intval($instance['cat_id']) : 0;
        $title = !empty($instance['title']) ? $instance['title'] : 'Последние записи';

        echo $args['before_widget'];
        echo $args['before_title'] . esc_html($title) . $args['after_title'];

        $cache_key = 'wpsell_recent_posts_' . $cat_id;
        $posts = get_transient($cache_key);

        if (false === $posts) {
            $query = new WP_Query([
                'cat' => $cat_id,
                'posts_per_page' => 3,
                'post_status' => 'publish'
            ]);
            if ($query->have_posts()) {
                $posts = [];
                while ($query->have_posts()) {
                    $query->the_post();
                    $posts[] = [
                        'title' => get_the_title(),
                        'permalink' => get_permalink()
                    ];
                }
                wp_reset_postdata();
                set_transient($cache_key, $posts, 3600); // кешируем на час
            } else {
                echo '<p>Нет записей для отображения.</p>';
                echo $args['after_widget'];
                return;
            }
        }

        echo '<ul>';
        foreach ($posts as $post) {
            echo '<li><a href="' . esc_url($post['permalink']) . '">' . esc_html($post['title']) . '</a></li>';
        }
        echo '</ul>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : '';
        $cat_id = !empty($instance['cat_id']) ? intval($instance['cat_id']) : 0;
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>">Заголовок:</label>
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('cat_id'); ?>">ID категории:</label>
            <input class="widefat" id="<?php echo $this->get_field_id('cat_id'); ?>" name="<?php echo $this->get_field_name('cat_id'); ?>" type="number" value="<?php echo esc_attr($cat_id); ?>" />
            <small>Укажите ID категории, из которой выводить записи</small>
        </p>
        <?php
    }

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

function wpsell_register_recent_posts_widget() {
    register_widget('WPSELL_Widget_RecentPosts');
}
add_action('widgets_init', 'wpsell_register_recent_posts_widget');

Этот виджет позволяет администратору указать заголовок и ID категории, а на сайте выводятся последние 3 записи из этой категории с кешированием для ускорения загрузки.

Как создать настройку отображения товара в WooCommerce на WordPress
15.11.2025
Как создать автоматическое сообщение о новых товарах WooCommerce через email
30.01.2026
Как отключить автоматическое удаление товаров WooCommerce при обновлении
17.05.2026
Как добавить вывод стоимости отсутствующих товаров в корзине WooCommerce
01.05.2026
Как создать и использовать шорткоды в WordPress
31.10.2025

Совсем скоро здесь заработает сайт о вордпресс. И будет он связан с продажами, магазинами или чем-то таким.