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

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

Что такое динамический виджет и зачем он нужен

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

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

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

Создание базового класса виджета WP_Themes_Dynamic_Widget

Начнём с создания собственного класса, унаследованного от WP_Widget. В классе нужно определить три обязательных метода:

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

Пример базового кода:

class WP_Themes_Dynamic_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wp_themes_dynamic_widget',
            __('WP Themes Динамический виджет', 'wp-themes'),
            ['description' => __('Пример динамического виджета', 'wp-themes')]
        );
    }

    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'];
        }
        // Вывод динамического контента
        echo '<p>Привет из динамического виджета!</p>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : __('Новый заголовок', 'wp-themes');
        ?>
        <p><label for="<?php echo $this->get_field_id('title'); ?>">Заголовок:</label></p>
        <p><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>
        <?php
    }

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

Этот код создаёт простой виджет с настраиваемым заголовком и статическим текстом.

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

Часто нужно вывести последние записи из выбранной категории. Для этого добавим в форму выбора категории, а в метод widget() — запрос постов.

Расширяем форму виджета

Добавим поле для выбора ID категории:

public function form($instance) {
    $title = !empty($instance['title']) ? $instance['title'] : __('Новый заголовок', 'wp-themes');
    $cat_id = !empty($instance['cat_id']) ? $instance['cat_id'] : 0;
    $categories = get_categories(['hide_empty' => false]);
    ?>
    <p><label for="<?php echo $this->get_field_id('title'); ?>">Заголовок:</label></p>
    <p><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'); ?>">Выберите категорию:</label></p>
    <p><select id="<?php echo $this->get_field_id('cat_id'); ?>" name="<?php echo $this->get_field_name('cat_id'); ?>" class="widefat">
        <option value="0">Все категории</option>
        <?php foreach ($categories as $category): ?>
            <option value="<?php echo $category->term_id; ?>" <?php selected($cat_id, $category->term_id); ?>><?php echo esc_html($category->name); ?></option>
        <?php endforeach; ?>
    </select></p>
    <?php
}

Обновляем метод update

public function update($new_instance, $old_instance) {
    $instance = [];
    $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
    $instance['cat_id'] = (!empty($new_instance['cat_id'])) ? intval($new_instance['cat_id']) : 0;
    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'];
    }
    $cat_id = !empty($instance['cat_id']) ? $instance['cat_id'] : 0;
    $query_args = [
        'posts_per_page' => 5,
        'post_status' => 'publish'
    ];
    if ($cat_id) {
        $query_args['cat'] = $cat_id;
    }
    $query = new WP_Query($query_args);
    if ($query->have_posts()) {
        echo '<ul>';
        while ($query->have_posts()) {
            $query->the_post();
            echo '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
        }
        echo '</ul>';
    } else {
        echo '<p>Нет записей для отображения.</p>';
    }
    wp_reset_postdata();
    echo $args['after_widget'];
}

Реализация кэширования для ускорения вывода

Чтобы снизить нагрузку на сайт, имеет смысл кешировать вывод виджета. WordPress предоставляет API транзиентов для этого.

Добавим кеширование в метод widget():

public function widget($args, $instance) {
    $cache_key = 'wp_themes_dynamic_widget_' . $this->id;
    $cache = get_transient($cache_key);
    if ($cache !== false) {
        echo $cache;
        return;
    }

    ob_start();
    echo $args['before_widget'];
    if (!empty($instance['title'])) {
        echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
    }
    $cat_id = !empty($instance['cat_id']) ? $instance['cat_id'] : 0;
    $query_args = ['posts_per_page' => 5, 'post_status' => 'publish'];
    if ($cat_id) $query_args['cat'] = $cat_id;
    $query = new WP_Query($query_args);
    if ($query->have_posts()) {
        echo '<ul>';
        while ($query->have_posts()) {
            $query->the_post();
            echo '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
        }
        echo '</ul>';
    } else {
        echo '<p>Нет записей для отображения.</p>';
    }
    wp_reset_postdata();
    echo $args['after_widget'];

    $output = ob_get_clean();
    set_transient($cache_key, $output, 12 * HOUR_IN_SECONDS); // кеш 12 часов
    echo $output;
}

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

Регистрируем виджет в WordPress

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

function wp_themes_register_dynamic_widget() {
    register_widget('WP_Themes_Dynamic_Widget');
}
add_action('widgets_init', 'wp_themes_register_dynamic_widget');

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

Вы можете добавить в виджет:

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

Эти расширения сделают ваш динамический виджет универсальным инструментом для сайта на WordPress.

Популярные плагины для динамических виджетов

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

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

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

Как создать адаптивную тему WordPress с нуля
31.10.2025
Как добавить динамические стили в тему WordPress
22.12.2025
Как удалить строку из вывода поста в WordPress
09.12.2025
Как создать динамический виджет в WordPress
26.11.2025
Глобальные хуки и фильтры в WordPress: практическое руководство от WP Themes
22.11.2025