Как создать собственный виджет в WordPress

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

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

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

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

  • Добавить кастомный вывод данных (например, последние отзывы, специальные акции);
  • Интегрировать сторонние API или сервисы;
  • Организовать удобный интерфейс управления данными в админке для клиентов.

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

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

Создание виджета сводится к написанию класса, который наследует WP_Widget, и регистрации этого класса в системе.

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

Шаг 1: Создание класса виджета

class WPTavern_Widget_Welcome extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wptavern_widget_welcome', // ID виджета
            'WPTavern: Приветствие', // Название
            ['description' => 'Простой виджет для приветствия посетителей']
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        $title = apply_filters('widget_title', $instance['title'] ?? 'Добро пожаловать!');
        $message = $instance['message'] ?? 'Спасибо, что посетили наш сайт!';

        if (!empty($title)) {
            echo $args['before_title'] . $title . $args['after_title'];
        }
        echo '<p>' . esc_html($message) . '</p>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = $instance['title'] ?? '';
        $message = $instance['message'] ?? '';
        ?>
        <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('message')); ?>">Сообщение:</label>
            <textarea class="widefat" id="<?php echo esc_attr($this->get_field_id('message')); ?>" name="<?php echo esc_attr($this->get_field_name('message')); ?>" rows="4"><?php echo esc_textarea($message); ?></textarea>
        </p>
        <?php
    }

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

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

Чтобы WordPress знал о нашем виджете, нужно зарегистрировать его в хуке widgets_init:

function wptavern_register_widgets() {
    register_widget('WPTavern_Widget_Welcome');
}
add_action('widgets_init', 'wptavern_register_widgets');

Расширение функционала виджета: динамические данные и шаблоны

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

Для примера создадим виджет, который выводит 5 последних публикаций с ссылками и миниатюрами.

Пример виджета с выводом последних записей

class WPTavern_Widget_Recent_Posts extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wptavern_widget_recent_posts',
            'WPTavern: Последние записи',
            ['description' => 'Выводит список последних записей с миниатюрами']
        );
    }

    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'] . $title . $args['after_title'];
        }

        $query = new WP_Query([
            'posts_per_page' => $number,
            'post_status' => 'publish'
        ]);

        if ($query->have_posts()) {
            echo '<ul class="wptavern-recent-posts">';
            while ($query->have_posts()) {
                $query->the_post();
                echo '<li>';
                if (has_post_thumbnail()) {
                    echo '<a href="' . esc_url(get_permalink()) . '">' . get_the_post_thumbnail(get_the_ID(), 'thumbnail') . '</a> ';
                }
                echo '<a href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a>';
                echo '</li>';
            }
            echo '</ul>';
            wp_reset_postdata();
        } else {
            echo '<p>Записей не найдено.</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 id="<?php echo esc_attr($this->get_field_id('number')); ?>" name="<?php echo esc_attr($this->get_field_name('number')); ?>" type="number" value="<?php echo esc_attr($number); ?>" min="1" max="20" />
        </p>
        <?php
    }

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

Плагины для удобной работы с виджетами

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

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

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

Отладка и тестирование виджетов

Во время разработки виджетов важно следить за следующими моментами:

  • Правильная регистрация ID и классов, чтобы избежать конфликтов.
  • Использование функций фильтрации и экранирования для безопасности (esc_html, sanitize_text_field и т.п.).
  • Тестирование в разных темах и с разными плагинами — иногда может влиять стилизация.
  • Проверка работы в мобильных браузерах.

Для отладки можно использовать error_log и WP_DEBUG режим.

Итоги

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

Отправка формы в WordPress без перезагрузки страницы с помощью AJAX
21.12.2025
WooCommerce: правильная настройка доставки по зонам — решение проблем с расчетом
30.04.2026
Как разрешить доступ к файлам в WordPress через .htaccess
02.02.2026
Обновление WordPress без перерыва в работе сайта
05.01.2026
Как создать динамическую пагинацию в WordPress без плагинов
29.01.2026