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

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

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

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

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

Далее мы рассмотрим, как зарегистрировать и создать виджет на основе класса, который наследуется от WP_Widget.

Регистрация и базовая структура виджета WordPress

Каждый виджет — это класс PHP, который наследуется от WP_Widget. Для начала создадим минимальный класс виджета и зарегистрируем его в системе.

class Wpma_Custom_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wpma_custom_widget', // ID виджета
            'WPMA: Пользовательский виджет', // Название
            array('description' => 'Пример собственного виджета WPMA')
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        echo '<p>Это мой первый виджет WPMA!</p>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        // Здесь будет форма настроек виджета
    }

    public function update($new_instance, $old_instance) {
        // Сохраняем настройки
        return $new_instance;
    }
}

function wpma_register_custom_widget() {
    register_widget('Wpma_Custom_Widget');
}
add_action('widgets_init', 'wpma_register_custom_widget');

Здесь мы создали класс Wpma_Custom_Widget, который выводит простой текст, и зарегистрировали его с помощью хука widgets_init. Если добавить этот код в файл functions.php вашей темы или в плагин — виджет появится в админке.

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

Чтобы виджет был удобным, нужно добавить параметры, которые пользователь сможет менять через админку. В методе form() рисуем форму настроек, а в update() сохраняем их.

Добавим поле для заголовка и текста:

public function form($instance) {
    $title = !empty($instance['title']) ? $instance['title'] : '';
    $text = !empty($instance['text']) ? $instance['text'] : '';
    ?>
    <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('text'); ?>">Текст:</label>
        <textarea class="widefat" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>" rows="4"><?php echo esc_textarea($text); ?></textarea>
    </p>
    <?php
}

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

Теперь в виджете можно задать заголовок и произвольный текст. В методе widget() выведем их:

public function widget($args, $instance) {
    echo $args['before_widget'];
    if (!empty($instance['title'])) {
        echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
    }
    if (!empty($instance['text'])) {
        echo '<p>' . esc_html($instance['text']) . '</p>';
    }
    echo $args['after_widget'];
}

Пример расширенного виджета: вывод последних постов с кастомными параметрами

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

Добавим в форму настройки поле для количества и выбора категории:

public function form($instance) {
    $title = !empty($instance['title']) ? $instance['title'] : '';
    $number = !empty($instance['number']) ? absint($instance['number']) : 5;
    $category = !empty($instance['category']) ? $instance['category'] : '';

    $categories = get_categories();
    ?>
    <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('number'); ?>">Количество постов:</label>
        <input id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="number" value="<?php echo esc_attr($number); ?>" min="1" max="20" style="width: 50px;" />
    </p>
    <p>
        <label for="<?php echo $this->get_field_id('category'); ?>">Категория:</label>
        <select id="<?php echo $this->get_field_id('category'); ?>" name="<?php echo $this->get_field_name('category'); ?>" class="widefat">
            <option value="">Все категории</option>
            <?php foreach ($categories as $cat) : ?>
                <option value="<?php echo $cat->slug; ?>" <?php selected($category, $cat->slug); ?>><?php echo esc_html($cat->name); ?></option>
            <?php endforeach; ?>
        </select>
    </p>
    <?php
}

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

В методе widget() сделаем запрос и выведем список постов:

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

    $query_args = array(
        'post_type' => 'post',
        'posts_per_page' => !empty($instance['number']) ? $instance['number'] : 5,
    );
    if (!empty($instance['category'])) {
        $query_args['category_name'] = $instance['category'];
    }

    $recent_posts = new WP_Query($query_args);

    if ($recent_posts->have_posts()) {
        echo '<ul>';
        while ($recent_posts->have_posts()) {
            $recent_posts->the_post();
            echo '<li><a href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></li>';
        }
        echo '</ul>';
    } else {
        echo '<p>Посты не найдены.</p>';
    }

    wp_reset_postdata();

    echo $args['after_widget'];
}

Рекомендации и лучшие практики при создании виджетов

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

  • Используйте префиксы в именах классов и функций, чтобы избежать конфликтов (как мы сделали с Wpma_).
  • Обрабатывайте пользовательский ввод через функции безопасности: esc_html, esc_attr, sanitize_text_field и др.
  • Не забывайте использовать wp_reset_postdata() после кастомных запросов WP_Query, чтобы не нарушить глобальный цикл.
  • Предоставляйте понятный интерфейс настроек с понятными подписями.
  • Тестируйте ваш виджет на разных темах и с разными плагинами, чтобы избежать конфликтов.

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

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

  • Widget Options — добавляет расширенные настройки виджетов, например, управление отображением по страницам, ролям пользователей.
  • Custom Sidebars — позволяет создавать собственные боковые панели и назначать их на разные страницы.
  • Black Studio TinyMCE Widget — расширяет стандартный текстовый виджет редактором TinyMCE, что упрощает форматирование.

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

Автоматическое удаление старых ревизий в WordPress для оптимизации базы данных
12.12.2025
WooCommerce: устранение проблем с корзиной и оплатой на WordPress
04.05.2026
WooCommerce: как исправить ошибку дублирования SKU товаров
28.06.2026
Как удалить или отключить плагин на определённых страницах WordPress
19.03.2026
Как создать автоматический запрос на данные в WordPress с помощью WP_Query и AJAX
02.03.2026