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

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

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

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

Разберёмся, как создать и зарегистрировать виджет на примере простого виджета с настраиваемым заголовком и текстом.

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

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

Основные методы класса виджета:

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

После создания класса виджет регистрируется с помощью хука widgets_init.

Пример базового шаблона виджета для wp-themes.ru

<?php
class WpThemes_Custom_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wp_themes_custom_widget',
            'WP-Themes: Кастомный виджет',
            array( 'description' => 'Простой настраиваемый виджет с заголовком и текстом' )
        );
    }

    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'] : '';
        $text = ! empty( $instance['text'] ) ? $instance['text'] : '';
        ?>
        <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( 'text' ) ); ?>">Текст:</label>
            <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $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'] = sanitize_text_field( $new_instance['title'] );
        $instance['text'] = sanitize_textarea_field( $new_instance['text'] );
        return $instance;
    }
}

function wp_themes_register_custom_widget() {
    register_widget( 'WpThemes_Custom_Widget' );
}
add_action( 'widgets_init', 'wp_themes_register_custom_widget' );
?>

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

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

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

В форме виджета добавим поле для URL изображения и ссылки, а в методе widget() выведем их с проверками.

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

<?php
class WpThemes_Advanced_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wp_themes_advanced_widget',
            'WP-Themes: Расширенный виджет',
            array( 'description' => 'Виджет с изображением, ссылкой и текстом' )
        );
    }

    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['image_url'] ) ) {
            $link_start = '';
            $link_end = '';
            if ( ! empty( $instance['link_url'] ) ) {
                $link_start = '<a href="' . esc_url( $instance['link_url'] ) . '">';
                $link_end = '</a>';
            }
            echo $link_start . '<img src="' . esc_url( $instance['image_url'] ) . '" alt="' . esc_attr( $instance['title'] ) . '" style="max-width:100%;height:auto;"/>' . $link_end;
        }
        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'] : '';
        $text = ! empty( $instance['text'] ) ? $instance['text'] : '';
        $image_url = ! empty( $instance['image_url'] ) ? $instance['image_url'] : '';
        $link_url = ! empty( $instance['link_url'] ) ? $instance['link_url'] : '';
        ?>
        <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( 'image_url' ) ); ?>">URL изображения:</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'image_url' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'image_url' ) ); ?>" type="text" value="<?php echo esc_attr( $image_url ); ?>" />
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'link_url' ) ); ?>">URL ссылки (необязательно):</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'link_url' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'link_url' ) ); ?>" type="text" value="<?php echo esc_attr( $link_url ); ?>" />
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>">Текст:</label>
            <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $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'] = sanitize_text_field( $new_instance['title'] );
        $instance['image_url'] = esc_url_raw( $new_instance['image_url'] );
        $instance['link_url'] = esc_url_raw( $new_instance['link_url'] );
        $instance['text'] = sanitize_textarea_field( $new_instance['text'] );
        return $instance;
    }
}

function wp_themes_register_advanced_widget() {
    register_widget( 'WpThemes_Advanced_Widget' );
}
add_action( 'widgets_init', 'wp_themes_register_advanced_widget' );
?>

Этот виджет позволяет задать заголовок, изображение с возможной ссылкой и произвольный текст. Для удобства загрузки изображений можно доработать форму с помощью JavaScript и медиа-загрузчика WordPress, но это уже тема для отдельной статьи.

Рекомендации по безопасности и производительности виджетов

При создании виджетов важно помнить о безопасности. Всегда используйте функции очистки данных, такие как sanitize_text_field, esc_url_raw, esc_html и esc_textarea, чтобы предотвратить XSS-атаки и другие уязвимости.

Также стоит оптимизировать вывод виджета, не выполняя тяжелых запросов в методе widget(). При необходимости кешируйте результаты или используйте transient API для сохранения промежуточных данных.

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

Заключение: где применять и как расширять собственные виджеты

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

Начинайте с простых виджетов, как показано в примерах, а затем добавляйте новые поля, интеграции и обработчики событий. Например, можно добавить AJAX-подгрузку, связь с REST API, динамические настройки и многое другое.

Используйте знания из этой статьи, чтобы создавать качественные виджеты под конкретные задачи и улучшать пользовательский опыт на wp-themes.ru и других сайтах на WordPress.

Как добавить поддержку AMP в тему WordPress
21.02.2026
Как создать тематический каталог тем WordPress с фильтрами и пагинацией
07.04.2026
Как убрать типичные PHP warnings и ошибки WooCommerce в теме WordPress
21.04.2026
Как создать адаптивные блоки в теме WordPress
15.02.2026
Как создать автообновляемые шаблоны для WordPress
29.12.2025