В WordPress виджеты — это мощный инструмент для добавления функциональности в боковые панели, футеры и другие области темы. Иногда готовые виджеты не подходят под конкретные задачи, и тогда возникает необходимость создать собственный объект виджета. В этой статье мы разберём, как это сделать правильно, подробно и с примерами кода.
Что такое объект виджета в WordPress и зачем его создавать
В WordPress виджет — это класс, унаследованный от WP_Widget. Он содержит методы для вывода контента, формы настроек в админке и сохранения данных. Создание своего виджета позволяет:
- Добавить уникальный функционал, которого нет в стандартных виджетах.
- Упростить управление контентом для пользователей без навыков программирования.
- Организовать вывод данных из сторонних API или базы данных.
Например, можно создать виджет с выводом последних отзывов, кастомным каталогом, или интерактивной формой.
Основные методы объекта виджета и их назначение
Чтобы создать собственный виджет, нужно определить класс, унаследованный от WP_Widget, и реализовать в нём минимум три основных метода:
__construct()— инициализация виджета, установка имени и описания.widget( $args, $instance )— вывод виджета на фронтенде.form( $instance )— вывод формы настроек в админке.update( $new_instance, $old_instance )— обработка и сохранение данных из формы настроек.
Дополнительно можно реализовать свои методы и подключать скрипты/стили.
Пример создания простого виджета с настройками
Создадим виджет WPSystem_Simple_Widget, который выводит заголовок и произвольный текст, заданный в настройках.
class WPSystem_Simple_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpsystem_simple_widget',
'WPSystem: Простой виджет',
['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' ) ); ?>"><?php echo esc_textarea( $text ); ?></textarea>
</p>
<?php
}
public function update( $new_instance, $old_instance ) {
$instance = [];
$instance['title'] = sanitize_text_field( $new_instance['title'] );
$instance['text'] = sanitize_textarea_field( $new_instance['text'] );
return $instance;
}
}После определения класса необходимо зарегистрировать виджет в WordPress:
function wpsystem_register_simple_widget() {
register_widget( 'WPSystem_Simple_Widget' );
}
add_action( 'widgets_init', 'wpsystem_register_simple_widget' );Теперь ваш виджет появится в разделе «Виджеты» панели администратора и его можно использовать в сайдбарах.
Расширение функционала: добавление кастомных стилей и скриптов в виджет
Чтобы улучшить внешний вид и интерактивность виджета, можно подключить отдельные CSS и JavaScript файлы. Рекомендуется делать это только если виджет активен, чтобы не грузить лишние ресурсы.
Пример подключения стилей и скриптов:
function wpsystem_enqueue_widget_assets() {
if ( is_active_widget( false, false, 'wpsystem_simple_widget', true ) ) {
wp_enqueue_style( 'wpsystem-widget-style', plugins_url( '/css/widget-style.css', __FILE__ ), [], '1.0' );
wp_enqueue_script( 'wpsystem-widget-script', plugins_url( '/js/widget-script.js', __FILE__ ), ['jquery'], '1.0', true );
}
}
add_action( 'wp_enqueue_scripts', 'wpsystem_enqueue_widget_assets' );В файлах widget-style.css и widget-script.js можно добавить нужные стили и логику. Например, плавное раскрытие текста или анимацию.
Практический пример: виджет с выводом последних отзывов с кастомной таксономией
Предположим, у вас есть кастомный тип записи review с таксономией категорий отзывов. Создадим виджет, который выводит последние 5 отзывов из выбранной категории.
Класс виджета будет выглядеть так:
class WPSystem_Review_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpsystem_review_widget',
'WPSystem: Последние отзывы',
['description' => 'Выводит последние отзывы из выбранной категории']
);
}
public function widget( $args, $instance ) {
echo $args['before_widget'];
$title = apply_filters( 'widget_title', $instance['title'] ?? 'Отзывы' );
if ( $title ) {
echo $args['before_title'] . esc_html( $title ) . $args['after_title'];
}
$category = sanitize_text_field( $instance['category'] ?? '' );
$query_args = [
'post_type' => 'review',
'posts_per_page' => 5,
'tax_query' => [],
];
if ( $category ) {
$query_args['tax_query'][] = [
'taxonomy' => 'review_category',
'field' => 'slug',
'terms' => $category,
];
}
$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'];
}
public function form( $instance ) {
$title = $instance['title'] ?? '';
$category = $instance['category'] ?? '';
// Получаем список категорий таксономии review_category
$terms = get_terms( [
'taxonomy' => 'review_category',
'hide_empty' => false,
] );
?>
<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( 'category' ) ); ?>">Категория отзывов:</label>
<select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'category' ) ); ?>">
<option value="">Все категории</option>
<?php foreach ( $terms as $term ) : ?>
<option value="<?php echo esc_attr( $term->slug ); ?>" <?php selected( $category, $term->slug ); ?>><?php echo esc_html( $term->name ); ?></option>
<?php endforeach; ?>
</select>
</p>
<?php
}
public function update( $new_instance, $old_instance ) {
$instance = [];
$instance['title'] = sanitize_text_field( $new_instance['title'] );
$instance['category'] = sanitize_text_field( $new_instance['category'] );
return $instance;
}
}Регистрация виджета происходит так же, как в предыдущем примере.
Советы по безопасности и производительности для виджетов
При создании виджетов важно учитывать несколько моментов:
- Всегда используйте функции
sanitize_*для очистки данных из формы. - Применяйте
esc_html,esc_attrи другие функции экранирования при выводе данных на страницу. - Избегайте сложных запросов в методе
widget(), лучше использовать кэширование результатов с помощью Transients API. - Поддерживайте совместимость с Gutenberg и новыми версиями WordPress.
Например, добавим кэширование для виджета с отзывами:
public function widget( $args, $instance ) {
echo $args['before_widget'];
$cache_key = 'wpsystem_review_widget_' . md5( serialize( $instance ) );
$output = get_transient( $cache_key );
if ( false === $output ) {
ob_start();
// Здесь код вывода виджета - как в примере выше
// ...
$output = ob_get_clean();
set_transient( $cache_key, $output, HOUR_IN_SECONDS );
}
echo $output;
echo $args['after_widget'];
}Использование плагина Clearfy Pro для управления виджетами
Если вы хотите оптимизировать работу виджетов и отключить неиспользуемые функции, плагин Clearfy Pro предлагает инструменты для управления виджетами и оптимизации кода, что помогает повысить производительность сайта.
Также Clearfy Pro позволяет скрывать виджеты для определённых ролей пользователей, что удобно для многоуровневых сайтов.
Заключение
Создание собственного объекта виджета в WordPress — задача выполнимая для любого разработчика с базовыми знаниями PHP и WP API. Такой подход даёт гибкость и расширяемость, позволяет создавать уникальные решения под задачи сайта. В статье мы рассмотрели основные методы, привели примеры и рекомендации по безопасности и производительности. Пробуйте, экспериментируйте и улучшайте свои сайты с помощью кастомных виджетов!