В этой статье мы подробно разберём, как создать собственный виджет для WordPress с нуля. Виджеты — это удобный способ добавить функциональность и контент в боковые панели, футеры и другие области вашего сайта. Несмотря на обилие готовых плагинов, иногда возникает необходимость создать уникальный виджет под конкретные задачи. Мы пройдём все основные этапы, обеспечим полноценный код и разъяснения, чтобы вы могли без проблем повторить этот процесс.
Что такое виджеты WordPress и зачем создавать свои?
Виджеты — это небольшие блоки с функционалом, которые администратор сайта может размещать в заранее определённых областях темы, называемых сайдбарами или областями виджетов. Они могут отображать текст, списки, изображения, формы, последние записи и многое другое.
Создавать собственные виджеты стоит, если:
- Нужно вывести специфическую информацию, которой нет в стандартных виджетах.
- Не хотите устанавливать лишние плагины, чтобы не нагружать сайт.
- Хотите интегрировать кастомный функционал, например, выводить данные из API или базы данных.
Теперь перейдём к практике.
Регистрация собственного виджета — основа
Для начала нужно создать класс, расширяющий WP_Widget. В нём определяются методы для отображения виджета, вывода формы настроек и сохранения данных.
Пример простого виджета wpbusiness, который выводит приветствие и настраиваемый текст:
<?php
class Wpbusiness_Custom_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpbusiness_custom_widget', // ID виджета
'WPBusiness: Приветственный виджет', // Название
array( '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 = array();
$instance['title'] = sanitize_text_field( $new_instance['title'] );
$instance['message'] = sanitize_textarea_field( $new_instance['message'] );
return $instance;
}
}
// Регистрация виджета
function wpbusiness_register_custom_widget() {
register_widget( 'Wpbusiness_Custom_Widget' );
}
add_action( 'widgets_init', 'wpbusiness_register_custom_widget' );
?>Этот код нужно добавить в файл вашего дочернего шаблона functions.php или в отдельный плагин.
Где разместить код и как подключать виджет
Лучший способ — сделать отдельный плагин для виджета. Это позволит переносить функционал между сайтами и не потерять изменения при обновлении темы.
Для простоты можно вставить код в functions.php активной темы, но тогда при смене темы виджет исчезнет.
Чтобы подключить виджет:
- Перейдите в консоль WordPress > Внешний вид > Виджеты.
- Найдите «WPBusiness: Приветственный виджет».
- Перетащите в нужную область сайдбара.
- Заполните поля заголовка и сообщения.
Расширяем виджет: добавляем настройки и динамический контент
Виджет становится мощнее, если добавить больше параметров. Например, добавим выбор цвета текста и ссылку.
Обновим форму настроек:
public function form( $instance ) {
$title = $instance['title'] ?? '';
$message = $instance['message'] ?? '';
$color = $instance['color'] ?? '#000000';
$link = $instance['link'] ?? '';
?>
<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>
<p>
<label for="<?php echo esc_attr($this->get_field_id( 'color' )); ?>">Цвет текста:</label>
<input class="widefat" type="color" id="<?php echo esc_attr($this->get_field_id( 'color' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'color' )); ?>" value="<?php echo esc_attr( $color ); ?>" />
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id( 'link' )); ?>">Ссылка (опционально):</label>
<input class="widefat" type="url" id="<?php echo esc_attr($this->get_field_id( 'link' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'link' )); ?>" value="<?php echo esc_attr( $link ); ?>" />
</p>
<?php
}И в методе widget() добавим вывод с использованием настройки цвета и ссылки:
public function widget( $args, $instance ) {
echo $args['before_widget'];
$title = apply_filters( 'widget_title', $instance['title'] ?? '');
$message = $instance['message'] ?? '';
$color = $instance['color'] ?? '#000000';
$link = $instance['link'] ?? '';
if ( ! empty( $title ) ) {
echo $args['before_title'] . $title . $args['after_title'];
}
$content = '<span style="color:' . esc_attr($color) . '">' . esc_html( $message ) . '</span>';
if ( ! empty( $link ) ) {
$content = '<a href="' . esc_url( $link ) . '" target="_blank" rel="noopener">' . $content . '</a>';
}
echo '<p>' . $content . '</p>';
echo $args['after_widget'];
}Полезные плагины для работы с виджетами и их настройками
Если хотите расширить возможности виджетов без программирования, рекомендую:
- Widget Options — добавляет расширенные настройки виджетов: видимость по страницам, устройствам, ролям пользователей.
- Content Aware Sidebars — позволяет создавать динамические боковые панели с уникальными виджетами для разных разделов сайта.
- Black Studio TinyMCE Widget — расширяет стандартный текстовый виджет возможностями визуального редактора TinyMCE.
Эти плагины существенно облегчают работу с виджетами и делают их более гибкими.
Советы по оптимизации и безопасности виджетов
При создании виджетов важно учитывать производительность и безопасность:
- Всегда используйте функции
esc_html(),esc_attr(),esc_url()для вывода данных, чтобы избежать XSS-уязвимостей. - Старайтесь минимизировать количество запросов к базе данных внутри виджета, кэшируйте результаты, если это возможно.
- Проверяйте и фильтруйте входящие данные в методе
update()для предотвращения сохранения вредоносного кода. - Тестируйте виджет в разных темах и с разными версиями WordPress для обеспечения совместимости.
Пример кэширования вывода виджета
Чтобы избежать лишних вычислений и ускорить загрузку, можно использовать встроенный кэш WordPress:
public function widget( $args, $instance ) {
$cache_key = 'wpbusiness_widget_cache_' . $this->id;
$cached = wp_cache_get( $cache_key );
if ( $cached ) {
echo $cached;
return;
}
ob_start();
// Ваш вывод виджета здесь
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'];
$output = ob_get_clean();
wp_cache_set( $cache_key, $output, '', 3600 ); // кэшируем на 1 час
echo $output;
}