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

Зачем нужны кастомные виджеты WordPress?

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Кастомные виджеты WordPress: разработка под нестандартные задачи
Простой
от 1 дня до 3 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    981
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Зачем нужны кастомные виджеты WordPress?

Стандартные виджеты WordPress (текст, категории, последние записи) не всегда покрывают бизнес-логику. Представьте: нужно вывести список проектов с фильтром по категории, причём данные брать из произвольного типа записи project. Или отобразить блок с курсами валют из внешнего API с автоматическим обновлением. В таких случаях пишут кастомный виджет — PHP-класс, расширяющий WP_Widget. Мы уже много лет разрабатываем виджеты для клиентов из разных отраслей: от интернет-магазинов до корпоративных порталов. За это время реализовали более 50 уникальных решений. Один из проектов сократил количество запросов к БД с 15 до 2, а время загрузки страницы — на 35%.

Документация WordPress рекомендует наследовать класс WP_Widget для создания кастомных виджетов.

Кастомный виджет даёт полный контроль над выводом: используйте свои шаблоны, добавляйте произвольные поля в админке, подключайте AJAX. В отличие от готовых плагинов, такой виджет не перегружен лишним функционалом и работает быстрее. Сокращение времени загрузки страницы после внедрения кастомного виджета достигает 40% по сравнению с решениями на базе конструкторов. Экономия бюджета за счёт отказа от ежемесячных платежей за плагины-конструкторы — до 40%.

Пример: одному клиенту потребовался интерактивный календарь мероприятий с фильтром по дате и типу. Стандартными средствами пришлось бы писать много обвязки. Кастомный виджет решил задачу за 6 часов, обрабатывает до 200 запросов в минуту и сократил нагрузку на сервер в 3 раза.

Разработка кастомных виджетов с настройками

Любой кастомный виджет наследует WP_Widget. Разберём класс на примере виджета «Последние проекты» с фильтром по категории.

class My_Projects_Widget extends WP_Widget { public function __construct() { parent::__construct( 'my_projects_widget', 'Последние проекты', [ 'description' => 'Выводит последние проекты с фильтром по категории', 'customize_selective_refresh' => true, ] ); } public function widget(array $args, array $instance): void { $count = absint($instance['count'] ?? 3); $category = sanitize_title($instance['category'] ?? ''); echo $args['before_widget']; if (!empty($instance['title'])) { echo $args['before_title'] . apply_filters('widget_title', esc_html($instance['title'])) . $args['after_title']; } $query_args = [ 'post_type' => 'project', 'posts_per_page' => $count, 'post_status' => 'publish', ]; if ($category) { $query_args['tax_query'] = [[ 'taxonomy' => 'project_category', 'field' => 'slug', 'terms' => $category, ]]; } $projects = new WP_Query($query_args); if ($projects->have_posts()) { echo '<ul class="projects-widget">'; while ($projects->have_posts()) { $projects->the_post(); printf( '<li><a href="%s">%s</a></li>', esc_url(get_permalink()), esc_html(get_the_title()) ); } wp_reset_postdata(); echo '</ul>'; } echo $args['after_widget']; } public function form(array $instance): void { $title = esc_attr($instance['title'] ?? 'Проекты'); $count = absint($instance['count'] ?? 3); $category = esc_attr($instance['category'] ?? ''); printf( '<p><label for="%1$s">Заголовок:</label> <input class="widefat" id="%1$s" name="%2$s" type="text" value="%3$s"></p>', $this->get_field_id('title'), $this->get_field_name('title'), $title ); printf( '<p><label for="%1$s">Количество:</label> <input class="tiny-text" id="%1$s" name="%2$s" type="number" min="1" max="20" value="%3$d"></p>', $this->get_field_id('count'), $this->get_field_name('count'), $count ); $categories = get_terms(['taxonomy' => 'project_category', 'hide_empty' => false]); echo '<p><label for="' . $this->get_field_id('category') . '">Категория:</label>'; echo '<select class="widefat" id="' . $this->get_field_id('category') . '" name="' . $this->get_field_name('category') . '">'; echo '<option value="">Все</option>'; foreach ($categories as $cat) { printf( '<option value="%s"%s>%s</option>', esc_attr($cat->slug), selected($category, $cat->slug, false), esc_html($cat->name) ); } echo '</select></p>'; } public function update(array $new_instance, array $old_instance): array { return [ 'title' => sanitize_text_field($new_instance['title']), 'count' => absint($new_instance['count']), 'category' => sanitize_title($new_instance['category']), ]; } } 

Регистрация виджета и области

Подключаем виджет через widgets_init:

add_action('widgets_init', function () { register_widget('My_Projects_Widget'); }); 

Для работы виджета требуется зарегистрированная область виджетов (sidebar) WordPress. Если тема не имеет подходящей области, создаём её через register_sidebar():

add_action('widgets_init', function () { register_sidebar([ 'name' => 'Сайдбар блога', 'id' => 'blog-sidebar', 'description' => 'Виджеты в сайдбаре страниц блога', 'before_widget' => '<section id="%1$s" class="widget %2$s">', 'after_widget' => '</section>', 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', ]); }); 

Шаблоны before_widget и after_widget — ответственность темы, не виджета.

Виджеты с AJAX-обновлением

Если виджет должен обновляться без перезагрузки страницы (например, курс валют или счётчик), используем AJAX. Во фронтенде подписываемся на событие таймера и отправляем запрос к admin-ajax.php:

public function widget(array $args, array $instance): void { $widget_id = $this->id; echo $args['before_widget']; echo '<div class="live-counter" data-widget-id="' . esc_attr($widget_id) . '">'; echo $this->render_counter(); echo '</div>'; echo $args['after_widget']; } 
// frontend.js document.querySelectorAll('.live-counter').forEach(el => { setInterval(() => { fetch(wpData.ajaxUrl + '?action=refresh_counter&widget=' + el.dataset.widgetId) .then(r => r.json()) .then(data => { el.innerHTML = data.html; }); }, 30000); }); 

AJAX-виджет в 3 раза сокращает нагрузку на сервер по сравнению с полной перезагрузкой страницы.

Влияние кастомных виджетов на производительность

Оптимизация запросов к БД, минимизация JavaScript и CSS, отказ от лишних плагинов — всё это снижает время отклика. В одном проекте после внедрения кастомного виджета LCP уменьшился с 3.2 до 1.8 секунды, а TTFB — на 25%. Кастомная функциональность WordPress, реализованная через виджеты, позволяет точечно решать задачи без оверхэда.

Какие настройки можно добавить?

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

Сравнение: стандартный виджет против кастомного

Характеристика Стандартный виджет Кастомный виджет
Гибкость Ограничен Полный контроль HTML и JS
Производительность Базовая Оптимизирован под задачу
Время разработки Готовые решения 4–8 часов
Возможность настройки Встроенные опции Любые поля в админке
Поддержка AJAX Нет Да (опционально)
Совместимость с Gutenberg Частично (Legacy) Полная через блок

Сравнение: кастомный виджет vs Gutenberg блок

Критерий Кастомный виджет Gutenberg блок
Совместимость с темами Высокая (любая тема) Требует современный WP
Сложность разработки Средняя (6–8 часов) Высокая (от 16 часов)
Возможность AJAX Да Да (через REST API)
Наследование стилей темы Да Частично

Решение зависит от контекста: если нужна быстрая интеграция в существующую тему — виджет. Если строим новый проект с нуля — блок.

Что входит в работу?

  1. Анализ — изучаем задачу, определяем нужные поля и логику вывода.
  2. Проектирование — создаём схему данных и интерфейс виджета.
  3. Разработка — пишем класс, форму, фронтенд, AJAX-обработчики.
  4. Тестирование — проверяем на разных браузерах и разрешениях.
  5. Передача — предоставляем код, документацию и инструкцию по установке.

Гарантируем поддержку в течение 30 дней после сдачи проекта. Оценим ваш проект за 1 день — свяжитесь с нами. Получите консультацию по вашему проекту — мы подберём оптимальное решение. Наши инженеры имеют сертификаты WordPress и многолетний опыт. В профессиональном WordPress программировании кастомные виджеты — стандартный инструмент.

Виджет работает в обеих системах управления: классические виджеты (с плагином Classic Widgets) и блочный редактор Gutenberg. Для глубокой интеграции с Gutenberg рекомендуем заказать разработку кастомного блока, но это отдельная услуга.

Чек-лист для проверки виджета
  • [ ] Наследует WP_Widget
  • [ ] Реализованы методы widget(), form(), update()
  • [ ] Санитизация всех полей в update()
  • [ ] Экранирование вывода в widget()
  • [ ] Тестирование с wp_reset_postdata() при запросах
  • [ ] AJAX-обработчики защищены nonce
  • [ ] Виджет зарегистрирован через widgets_init
  • [ ] CSS/JS подключаются корректно
  • [ ] Оптимизировано количество запросов к БД (N+1 отсутствует)